Merge pull request #3913 from omwok/master
authorAlexander Köplinger <alex.koeplinger@outlook.com>
Tue, 8 Nov 2016 12:57:16 +0000 (13:57 +0100)
committerGitHub <noreply@github.com>
Tue, 8 Nov 2016 12:57:16 +0000 (13:57 +0100)
column name and ordinal fix.

419 files changed:
configure.ac
eglib/src/goutput.c
external/boringssl
external/nunit-lite
mcs/build/Makefile
mcs/build/config-default.make
mcs/build/nunit-summary.xsl [deleted file]
mcs/build/platforms/win32.make
mcs/build/profiles/mobile_static.make
mcs/build/profiles/monotouch_runtime.make
mcs/build/profiles/xammac.make
mcs/build/profiles/xammac_net_4_5.make
mcs/build/rules.make
mcs/build/tests.make
mcs/class/Microsoft.Build.Engine/.gitignore
mcs/class/Microsoft.Build.Engine/Makefile
mcs/class/Microsoft.Build.Framework/.gitignore [new file with mode: 0644]
mcs/class/Microsoft.Build.Framework/Makefile
mcs/class/Microsoft.Build.Tasks/.gitignore
mcs/class/Microsoft.Build.Tasks/Makefile
mcs/class/Microsoft.Build.Tasks/Test/test-config-file-net-4.0 [deleted file]
mcs/class/Microsoft.Build.Utilities/.gitignore [new file with mode: 0644]
mcs/class/Microsoft.Build.Utilities/Makefile
mcs/class/Microsoft.Build/.gitignore
mcs/class/Microsoft.Build/Makefile
mcs/class/Microsoft.Build/Microsoft.Build.Internal/BuildNodeManager.cs
mcs/class/Microsoft.Build/Microsoft.Build_test.dll.sources
mcs/class/Mono.CodeContracts/Mono.CodeContracts_test.dll.sources
mcs/class/Mono.CompilerServices.SymbolWriter/SourceMethodBuilder.cs
mcs/class/Mono.Parallel/Mono.Parallel_test.dll.sources
mcs/class/Mono.Posix/Mono.Posix_test.dll.sources
mcs/class/Mono.Posix/Test/Mono.Unix.Native/RealTimeSignumTests.cs
mcs/class/Mono.Posix/Test/Mono.Unix.Native/SocketTest.cs
mcs/class/Mono.Posix/Test/Mono.Unix.Native/StdlibTest.cs
mcs/class/Mono.Posix/Test/Mono.Unix/ReadlinkTest.cs
mcs/class/Mono.Posix/Test/Mono.Unix/UnixEndPointTest.cs
mcs/class/Mono.Posix/Test/Mono.Unix/UnixGroupTest.cs
mcs/class/Mono.Posix/Test/Mono.Unix/UnixListenerTest.cs
mcs/class/Mono.Posix/Test/Mono.Unix/UnixMarshalTest.cs
mcs/class/Mono.Posix/Test/Mono.Unix/UnixPathTest.cs
mcs/class/Mono.Posix/Test/Mono.Unix/UnixSignalTest.cs
mcs/class/Mono.Posix/Test/Mono.Unix/UnixUserTest.cs
mcs/class/Mono.Reactive.Testing/Makefile
mcs/class/Mono.Security/Test/tools/sockethell/Makefile
mcs/class/Mono.XBuild.Tasks/.gitignore [new file with mode: 0644]
mcs/class/Mono.XBuild.Tasks/Makefile
mcs/class/Mono.XBuild.Tasks/Mono.XBuild.Tasks_test.dll.sources
mcs/class/System.Configuration/Makefile
mcs/class/System.Configuration/Test/App.config [deleted file]
mcs/class/System.Configuration/Test/System.Configuration/AppSettingsSectionTest.cs
mcs/class/System.Configuration/Test/System.Configuration/ConfigurationManagerTest.cs
mcs/class/System.Configuration/Test/System.Configuration/ConfigurationSaveTest.cs
mcs/class/System.Configuration/Test/Util/TestUtil.cs
mcs/class/System.Configuration/Test/test-config-file [new file with mode: 0644]
mcs/class/System.Configuration/net_4_x_System.Configuration_test.dll.config [deleted file]
mcs/class/System.Core/Microsoft.Win32.SafeHandles/SafeMemoryMappedViewHandle.cs
mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedFile.cs
mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedView.cs
mcs/class/System.Core/Test/System.IO.MemoryMappedFiles/MemoryMappedFileTest.cs
mcs/class/System.Core/Test/System.Linq/EnumerableFixture.cs
mcs/class/System.Data.Linq/build/.gitignore [new file with mode: 0644]
mcs/class/System.Data.Linq/build/DbLinq.Sqlite_test_mono_strict.dll.sources
mcs/class/System.Data.Linq/build/Makefile
mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/DataContext.cs
mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/DynamicLinqTest.cs
mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/ExecuteCommand_Test.cs
mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/ExecuteQuery_Test.cs
mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/Linq_101_Samples/Advanced.cs
mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/ReadTest.cs
mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/ReadTest_Complex.cs
mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/ReadTest_GroupBy.cs
mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/ReadTests_AnyCountFirst.cs
mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/ReadTests_DateTimeFunctions.cs
mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/ReadTests_EntitySet.cs
mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/StoredProcTest.cs
mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/Table.cs
mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/TestBase.cs
mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/WriteTest.cs
mcs/class/System.Data.OracleClient/README.tests
mcs/class/System.Data.OracleClient/System.Data.OracleClient_test_default.dll.config.example [deleted file]
mcs/class/System.Data.OracleClient/Test/System.Data.OracleClient.Oci/OciDefineHandleTest.cs
mcs/class/System.Data.OracleClient/Test/System.Data.OracleClient.jvm/GHTDB.ORACLE.sql
mcs/class/System.Data.OracleClient/Test/System.Data.OracleClient.jvm/MonoTests.System.Data.Utils/ConnectedDataProvider.cs
mcs/class/System.Data.OracleClient/Test/System.Data.OracleClient.jvm/OracleConnection/IDBConnection_For_Oracle.cs
mcs/class/System.Data.OracleClient/Test/System.Data.OracleClient.jvm/readme.txt
mcs/class/System.Data.OracleClient/Test/System.Data.OracleClient/OracleLobTest.cs
mcs/class/System.Data.OracleClient/Test/System.Data.OracleClient/OracleParameterTest.cs
mcs/class/System.Data/Makefile
mcs/class/System.Data/System.Data.SqlClient/SqlConnection.cs
mcs/class/System.Data/Test/System.Data/ConstraintCollectionTest.cs
mcs/class/System.Data/Test/System.Data/ConstraintTest.cs
mcs/class/System.Data/Test/System.Data/DataRelationCollectionTest.cs
mcs/class/System.Data/Test/System.Data/DataRelationTest.cs
mcs/class/System.Data/Test/System.Data/TypedDataSetGeneratorTest.cs
mcs/class/System.Data/Test/System.Data/UniqueConstraintTest.cs
mcs/class/System.Data/Test/test-config-file [new file with mode: 0644]
mcs/class/System.Data/app_test_mobile_static.config [deleted file]
mcs/class/System.Data/app_test_net_4_x.config [deleted file]
mcs/class/System.Drawing/System.Drawing_test.dll.sources
mcs/class/System.Drawing/Test/DrawingTest/Test/Graphics.cs
mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Ipc.Win32/IpcChannel.cs
mcs/class/System.Runtime.Remoting/System.Runtime.Remoting_test.dll.sources
mcs/class/System.Runtime.Remoting/Test/HttpBugTests.cs
mcs/class/System.Runtime.Remoting/Test/IpcChannelTest.cs
mcs/class/System.Runtime.Remoting/Test/RemotingServicesTest.cs
mcs/class/System.Runtime.Serialization/Test/System.Runtime.Serialization/CollectionSerialization.cs
mcs/class/System.Runtime.Serialization/Test/System.Runtime.Serialization/XsdDataContractExporterTest2.cs
mcs/class/System.Runtime.Serialization/Test/System.Runtime.Serialization/XsdDataContractImporterTest2.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageFault.cs
mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ChannelDispatcher.cs
mcs/class/System.ServiceModel/System.ServiceModel_test.dll.sources
mcs/class/System.ServiceModel/Test/MetadataTests/BindingTestAssertions.cs
mcs/class/System.ServiceModel/Test/MetadataTests/ExportTests.cs
mcs/class/System.ServiceModel/Test/MetadataTests/ImportTests.cs
mcs/class/System.ServiceModel/Test/MetadataTests/ImportTests_LoadMetadata.cs
mcs/class/System.ServiceModel/Test/MetadataTests/MiscImportTests.cs
mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/MessageEncoderTest.cs
mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/MessageFaultTest.cs
mcs/class/System.ServiceProcess/System.ServiceProcess_test.dll.sources
mcs/class/System.Threading.Tasks.Dataflow/System.Threading.Tasks.Dataflow_test.dll.sources
mcs/class/System.Threading.Tasks.Dataflow/Test/System.Threading.Tasks.Dataflow/BoundedCapacityTest.cs
mcs/class/System.Threading.Tasks.Dataflow/Test/System.Threading.Tasks.Dataflow/DataflowBlockTest.cs
mcs/class/System.Threading.Tasks.Dataflow/Test/System.Threading.Tasks.Dataflow/OptionsTest.cs
mcs/class/System.Web.DynamicData/System.Web.DynamicData_test.dll.sources
mcs/class/System.Web.DynamicData/Test/Common/Mocks.cs [deleted file]
mcs/class/System.Web.DynamicData/Test/System.Web.DynamicData/DynamicControlTest.cs
mcs/class/System.Web.DynamicData/Test/System.Web.DynamicData/DynamicDataRouteHandlerTest.cs
mcs/class/System.Web.DynamicData/Test/System.Web.DynamicData/DynamicDataRouteTest.cs
mcs/class/System.Web.DynamicData/Test/System.Web.DynamicData/DynamicValidatorTest.cs
mcs/class/System.Web.DynamicData/Test/System.Web.DynamicData/FieldTemplateFactoryTest.cs
mcs/class/System.Web.DynamicData/Test/System.Web.DynamicData/FieldTemplateUserControlTest.cs
mcs/class/System.Web.DynamicData/Test/System.Web.DynamicData/MetaColumnTest.cs
mcs/class/System.Web.DynamicData/Test/System.Web.DynamicData/MetaModelTest.cs
mcs/class/System.Web.DynamicData/Test/System.Web.DynamicData/MetaTableTest.cs
mcs/class/System.Web/System.Web_standalone_test.dll.sources
mcs/class/System.Web/System.Web_test.dll.sources
mcs/class/System.Web/Test/System.Web.Hosting/HostingEnvironmentTest.cs
mcs/class/System.Web/Test/System.Web/HttpResponseTest.cs
mcs/class/System.Web/Test/System.Web/HttpRuntimeTest.cs
mcs/class/System.Web/Test/System.Web/XmlSiteMapProviderTest.cs
mcs/class/System.Windows.Forms/System.Windows.Forms_test.dll.sources
mcs/class/System.Windows.Forms/Test/System.Resources/ResXDataNodeFileRefGetValueTests.cs
mcs/class/System.Windows.Forms/Test/System.Resources/ResXDataNodeSerialisedGetValueTypeNameTests.cs
mcs/class/System.Windows.Forms/Test/System.Resources/ResXDataNodeSerializedGetValueTests.cs
mcs/class/System.Windows.Forms/Test/System.Resources/ResXDataNodeTest.cs
mcs/class/System.Windows.Forms/Test/System.Resources/ResXDataNodeWriteBehavior.cs
mcs/class/System.Windows.Forms/Test/System.Windows.Forms/ApplicationTest.cs
mcs/class/System.Windows.Forms/Test/System.Windows.Forms/TableLayoutTest.cs
mcs/class/System.XML/Test/System.Xml.Serialization/XmlCodeExporterTests.cs
mcs/class/System.XML/Test/System.Xml/XmlSecureResolverTests.cs
mcs/class/System.Xml.Linq/System.Xml.Linq_test.dll.sources
mcs/class/System.Xml.Linq/Test/System.Xml.Schema/ExtensionsTest.cs
mcs/class/System/Makefile
mcs/class/System/Mono.Btls/MonoBtlsX509Lookup.cs
mcs/class/System/Mono.Btls/MonoBtlsX509NameList.cs [deleted file]
mcs/class/System/Mono.Net.Security/MonoTlsProviderFactory.Droid.cs
mcs/class/System/ReferenceSources/HttpApi.cs
mcs/class/System/ReferenceSources/SecureStringHelper.cs [new file with mode: 0644]
mcs/class/System/System-bare-net_4_x.csproj
mcs/class/System/System-net_4_x.csproj
mcs/class/System/System-secxml-net_4_x.csproj
mcs/class/System/System.Net.Sockets/Socket.cs
mcs/class/System/System.Net/NetworkCredential.cs [deleted file]
mcs/class/System/System.dll.sources
mcs/class/System/System/AndroidPlatform.cs
mcs/class/System/System_test.dll.sources
mcs/class/System/Test/System.CodeDom.Compiler/CodeGeneratorGenerateFromCompileUnitTest.cs
mcs/class/System/Test/System.Collections.Generic/SortedListTest.cs
mcs/class/System/Test/System.Diagnostics/SourceSwitchTest.cs
mcs/class/System/Test/System.Diagnostics/SwitchesTest.cs
mcs/class/System/Test/System.IO.Compression/DeflateStreamTest.cs
mcs/class/System/Test/System.Net/NetworkCredentialTest.cs
mcs/class/System/Test/System.Security.Cryptography.X509Certificates/PkitsTest.cs
mcs/class/System/Test/compressed.bin [new file with mode: 0644]
mcs/class/System/Test/test-config-file
mcs/class/System/Test/test-config-file-net-2.0 [deleted file]
mcs/class/System/mobile_System.dll.sources
mcs/class/WebMatrix.Data/WebMatrix.Data_test.dll.sources
mcs/class/WindowsBase/WindowsBase_test.dll.sources
mcs/class/corlib/ReferenceSources/SharedStatics.cs [deleted file]
mcs/class/corlib/System.Runtime.InteropServices/Marshal.cs
mcs/class/corlib/System.Security.Cryptography/CryptoConfig.cs
mcs/class/corlib/System.Threading/Thread.cs
mcs/class/corlib/System/Environment.cs
mcs/class/corlib/Test/Mono/DataConvertTest.cs
mcs/class/corlib/Test/System.Collections.Concurrent/ConcurrentDictionaryTests.cs
mcs/class/corlib/Test/System.Collections.Concurrent/PartitionerTests.cs
mcs/class/corlib/Test/System.IO.IsolatedStorage/IsolatedStorageFileStreamTest.cs
mcs/class/corlib/Test/System.Runtime.CompilerServices/TaskAwaiterTest.cs
mcs/class/corlib/Test/System.Runtime.InteropServices/MarshalTest.cs
mcs/class/corlib/Test/System.Security.AccessControl/RawSecurityDescriptorTest.cs
mcs/class/corlib/Test/System.Security.Cryptography/SignatureDescriptionTest.cs
mcs/class/corlib/Test/System.Text/ASCIIEncodingTest.cs
mcs/class/corlib/Test/System.Text/Latin1EncodingTest.cs
mcs/class/corlib/Test/System.Text/UTF8EncodingTest.cs
mcs/class/corlib/Test/System.Threading.Tasks/TaskCompletionSourceTests.cs
mcs/class/corlib/Test/System.Threading.Tasks/TaskFactoryTest.cs
mcs/class/corlib/Test/System.Threading.Tasks/TaskFactoryTest_T.cs
mcs/class/corlib/Test/System.Threading.Tasks/TaskSchedulerTest.cs
mcs/class/corlib/Test/System.Threading.Tasks/TaskTest.cs
mcs/class/corlib/Test/System.Threading/ThreadLocalTests.cs
mcs/class/corlib/Test/System/SingleTest.cs
mcs/class/corlib/Test/System/TypeTest.cs
mcs/class/corlib/corlib-net_4_x.csproj
mcs/class/corlib/corlib.dll.sources
mcs/class/corlib/corlib_test.dll.sources
mcs/class/monodoc/Test/Monodoc.Generators/RawGeneratorTests.cs
mcs/class/monodoc/Test/Monodoc/HelpSourceTests.cs
mcs/class/monodoc/Test/Monodoc/SettingsTest.cs
mcs/class/monodoc/monodoc_test.dll.sources
mcs/class/referencesource/System/net/System/Net/NetworkCredential.cs
mcs/class/referencesource/mscorlib/system/sharedstatics.cs
mcs/class/test-helpers/NunitHelpers.cs [new file with mode: 0644]
mcs/errors/cs1691-2.cs [deleted file]
mcs/errors/cs1691-3.cs [deleted file]
mcs/errors/cs1691-4.cs [deleted file]
mcs/errors/cs1691.cs [deleted file]
mcs/errors/cs1744-3.cs [new file with mode: 0644]
mcs/errors/cs1904.cs [deleted file]
mcs/mcs/ecore.cs
mcs/mcs/iterators.cs
mcs/mcs/report.cs
mcs/mcs/settings.cs
mcs/mcs/statement.cs
mcs/tests/test-debug-11-ref.xml
mcs/tests/test-debug-21-ref.xml
mcs/tests/test-debug-28-ref.xml
mcs/tests/test-debug-31-ref.xml [new file with mode: 0644]
mcs/tests/test-debug-31.cs [new file with mode: 0644]
mcs/tests/test-debug-32-ref.xml [new file with mode: 0644]
mcs/tests/test-debug-32.cs [new file with mode: 0644]
mcs/tests/test-named-10.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_x.xml
mcs/tools/corcompare/mono-api-info.csproj
mcs/tools/linker/Tests/Makefile
mcs/tools/mono-api-html/Makefile
mcs/tools/mono-api-html/mono-api-html-net_4_x.csproj
mcs/tools/nunit-lite/NUnitLite/BabysitterSupport.cs [new file with mode: 0644]
mcs/tools/nunit-lite/NUnitLite/nunitlite.dll.sources
mcs/tools/nunit-lite/nunit-lite-console/nunit-lite-console.exe.config [deleted file]
mcs/tools/nunit-lite/nunit-lite-console/nunit-lite-console.exe.config.tmpl [new file with mode: 0644]
mcs/tools/xbuild/Makefile
mcs/tools/xbuild/data/xbuild.exe.config_test.in [new file with mode: 0644]
mcs/tools/xbuild/xbuild_test.make
mono/btls/CMakeLists.txt
mono/btls/Makefile.am
mono/btls/btls-android-utils.c [deleted file]
mono/btls/btls-bio.c
mono/btls/btls-bio.h
mono/btls/btls-time64.c [new file with mode: 0644]
mono/btls/btls-util.c
mono/btls/btls-util.h
mono/btls/btls-x509-crl.c
mono/btls/btls-x509-crl.h
mono/btls/btls-x509-lookup-mono.c
mono/btls/btls-x509-name.c
mono/btls/btls-x509-name.h
mono/btls/btls-x509-revoked.c
mono/btls/btls-x509-revoked.h
mono/btls/btls-x509-verify-param.c
mono/btls/btls-x509-verify-param.h
mono/btls/btls-x509.c
mono/btls/btls-x509.h
mono/dis/get.c
mono/io-layer/Makefile.am
mono/io-layer/access.h [deleted file]
mono/io-layer/error.c
mono/io-layer/io.c
mono/io-layer/locking.c
mono/io-layer/posix.c
mono/io-layer/process-private.h [deleted file]
mono/io-layer/processes.c [deleted file]
mono/io-layer/processes.h [deleted file]
mono/io-layer/sockets.c
mono/io-layer/timefuncs-private.h [deleted file]
mono/io-layer/timefuncs.c
mono/io-layer/timefuncs.h
mono/io-layer/uglify.h
mono/io-layer/wait.c
mono/io-layer/wait.h
mono/io-layer/wapi-private.h
mono/io-layer/wapi-remap.h
mono/io-layer/wapi.c
mono/io-layer/wapi.h
mono/metadata/Makefile.am
mono/metadata/appdomain.c
mono/metadata/assembly.c
mono/metadata/attach.c
mono/metadata/boehm-gc.c
mono/metadata/class-accessors.c [new file with mode: 0644]
mono/metadata/class-inlines.h [new file with mode: 0644]
mono/metadata/class-internals.h
mono/metadata/class.c
mono/metadata/cominterop.c
mono/metadata/custom-attrs-internals.h
mono/metadata/custom-attrs.c
mono/metadata/domain.c
mono/metadata/file-io.c
mono/metadata/file-mmap-posix.c
mono/metadata/file-mmap-windows.c
mono/metadata/gc-internals.h
mono/metadata/gc.c
mono/metadata/handle.c
mono/metadata/icall-def.h
mono/metadata/icall-internals.h
mono/metadata/icall-windows-uwp.c
mono/metadata/icall-windows.c
mono/metadata/icall.c
mono/metadata/image.c
mono/metadata/loader.c
mono/metadata/marshal-internals.h
mono/metadata/marshal-windows.c
mono/metadata/marshal.c
mono/metadata/metadata.c
mono/metadata/metadata.h
mono/metadata/object-internals.h
mono/metadata/object-offsets.h
mono/metadata/object.c
mono/metadata/process-internals.h [deleted file]
mono/metadata/process-windows-internals.h [deleted file]
mono/metadata/process-windows-uwp.c [deleted file]
mono/metadata/process-windows.c [deleted file]
mono/metadata/process.c [deleted file]
mono/metadata/process.h [deleted file]
mono/metadata/reflection-internals.h
mono/metadata/reflection.c
mono/metadata/seq-points-data.c
mono/metadata/sgen-mono.c
mono/metadata/sgen-new-bridge.c
mono/metadata/sgen-tarjan-bridge.c
mono/metadata/socket-io.c
mono/metadata/sre-encode.c
mono/metadata/sre-save.c
mono/metadata/sre.c
mono/metadata/threadpool-ms.c
mono/metadata/threads-types.h
mono/metadata/threads.c
mono/metadata/verify.c
mono/metadata/w32event-unix.c
mono/metadata/w32handle-namespace.h
mono/metadata/w32handle.c [new file with mode: 0644]
mono/metadata/w32handle.h [new file with mode: 0644]
mono/metadata/w32mutex-unix.c
mono/metadata/w32process-internals.h [new file with mode: 0644]
mono/metadata/w32process-unix-bsd.c [new file with mode: 0644]
mono/metadata/w32process-unix-default.c [new file with mode: 0644]
mono/metadata/w32process-unix-haiku.c [new file with mode: 0644]
mono/metadata/w32process-unix-internals.h [new file with mode: 0644]
mono/metadata/w32process-unix-osx.c [new file with mode: 0644]
mono/metadata/w32process-unix.c [new file with mode: 0644]
mono/metadata/w32process-win32-internals.h [new file with mode: 0644]
mono/metadata/w32process-win32-uwp.c [new file with mode: 0644]
mono/metadata/w32process-win32.c [new file with mode: 0644]
mono/metadata/w32process.c [new file with mode: 0644]
mono/metadata/w32process.h [new file with mode: 0644]
mono/metadata/w32semaphore-unix.c
mono/mini/aot-compiler.c
mono/mini/aot-runtime.c
mono/mini/branch-opts.c
mono/mini/debugger-agent.c
mono/mini/driver.c
mono/mini/exceptions-arm64.c
mono/mini/jit-icalls.c
mono/mini/main.c
mono/mini/method-to-ir.c
mono/mini/mini-arm.c
mono/mini/mini-arm.h
mono/mini/mini-codegen.c
mono/mini/mini-darwin.c
mono/mini/mini-exceptions.c
mono/mini/mini-generic-sharing.c
mono/mini/mini-llvm-cpp.cpp
mono/mini/mini-llvm.c
mono/mini/mini-runtime.c
mono/mini/mini-s390x.c
mono/mini/mini-trampolines.c
mono/mini/mini.c
mono/mini/mini.h
mono/mini/patch-info.h
mono/mini/trace.c
mono/mini/tramp-amd64.c
mono/sgen/sgen-gc.h
mono/tests/Makefile.am
mono/tests/appdomain-threadpool-unload.cs [new file with mode: 0644]
mono/tests/custom-attr-errors.cs
mono/tests/sgen-new-threads-collect.cs [new file with mode: 0644]
mono/tests/thread-suspend-suspended.cs [new file with mode: 0644]
mono/unit-tests/test-conc-hashtable.c
mono/utils/Makefile.am
mono/utils/mach-support-amd64.c
mono/utils/mach-support-arm.c
mono/utils/mach-support-arm64.c
mono/utils/mach-support-unknown.c
mono/utils/mach-support-x86.c
mono/utils/mach-support.h
mono/utils/mono-codeman.c
mono/utils/mono-context.c
mono/utils/mono-context.h
mono/utils/mono-mmap-windows.c
mono/utils/mono-mmap.c
mono/utils/mono-mmap.h
mono/utils/mono-sigcontext.h
mono/utils/mono-threads-coop.c
mono/utils/mono-threads-mach.c
mono/utils/mono-threads-posix.c
mono/utils/mono-threads-windows.c
mono/utils/mono-threads.c
mono/utils/mono-threads.h
mono/utils/os-event-unix.c
mono/utils/w32handle.c [deleted file]
mono/utils/w32handle.h [deleted file]
msvc/libmonoruntime.vcxproj
msvc/libmonoruntime.vcxproj.filters
msvc/pedump.vcxproj
msvc/pedump.vcxproj.filters
msvc/scripts/order.xml
scripts/ci/run-test-default.sh
support/zlib-helper.c
tools/monograph/monograph.c

index 43111ecc3ca6ebe44ef9c957f4484bc2b353271f..45dbacccdb6ffb8c8e349b76df8ce4f2040cf579 100644 (file)
@@ -763,7 +763,7 @@ DISABLED_FEATURES=none
 # Set the build profiles and options before things which use them
 #
 
-AC_ARG_WITH(profile4_x,      [  --with-profile4=yes,no          If you want to install the 4.x FX (defaults to yes)],                 [], [with_profile4_x=default])
+AC_ARG_WITH(profile4_x,      [  --with-profile4_x=yes,no        If you want to install the 4.x FX (defaults to yes)],                 [], [with_profile4_x=default])
 AC_ARG_WITH(monodroid,       [  --with-monodroid=yes,no         If you want to build the MonoDroid assemblies (defaults to no)],      [], [with_monodroid=default])
 AC_ARG_WITH(monotouch,       [  --with-monotouch=yes,no         If you want to build the Xamarin.iOS assemblies (defaults to no)],    [], [with_monotouch=default])
 AC_ARG_WITH(monotouch_watch, [  --with-monotouch_watch=yes,no   If you want to build the Xamarin.WatchOS assemblies (defaults to no)],[], [with_monotouch_watch=default])
index ef80cff034748e559dea3055bc3bfb175dc3eb76..2dcf8746e08a90a3d3f506d7a19849b93db60295 100644 (file)
@@ -47,8 +47,10 @@ g_print (const gchar *format, ...)
        va_list args;
 
        va_start (args, format);
-       if (g_vasprintf (&msg, format, args) < 0)
+       if (g_vasprintf (&msg, format, args) < 0) {
+               va_end (args);
                return;
+       }
        va_end (args);
 
        if (!stdout_handler)
@@ -65,8 +67,10 @@ g_printerr (const gchar *format, ...)
        va_list args;
 
        va_start (args, format);
-       if (g_vasprintf (&msg, format, args) < 0)
+       if (g_vasprintf (&msg, format, args) < 0) {
+               va_end (args);
                return;
+       }
        va_end (args);
 
        if (!stderr_handler)
index 432738a3c938b4f751307301c6aa07f2027a8864..c06ac6b33d3e7442ad878488b9d1100127eff998 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 432738a3c938b4f751307301c6aa07f2027a8864
+Subproject commit c06ac6b33d3e7442ad878488b9d1100127eff998
index 4bc79a6da1f0ee538560b7e4d0caff46d3c86e4f..dda48cd0343bddac6b3faf0c0498b680468cc3fd 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 4bc79a6da1f0ee538560b7e4d0caff46d3c86e4f
+Subproject commit dda48cd0343bddac6b3faf0c0498b680468cc3fd
index f33fcccf2d7635f498496404d5ed0dbadd8f1d56..14ad0cbd10c74283e2d25bc4cb1682d77c5dcb90 100644 (file)
@@ -41,7 +41,6 @@ DISTFILES = \
        executable.make                 \
        gensources.sh                   \
        library.make                    \
-       nunit-summary.xsl               \
        rules.make                      \
        tests.make                      \
        $(COMMON_SRCS:%=common/%)       \
index 145665799ccaaccd74e1c7a9617f8f1d725da98b..9e4fcf64a306bda16b94c324ae81371f7e951156 100644 (file)
@@ -10,7 +10,7 @@
 CODEPAGE = 65001
 
 RUNTIME_FLAGS = 
-TEST_HARNESS = $(topdir)/class/lib/$(PROFILE)/$(PARENT_PROFILE)nunit-console.exe
+TEST_HARNESS = $(topdir)/class/lib/$(PROFILE)/$(PARENT_PROFILE)nunit-lite-console.exe
 MCS_FLAGS = 
 MBAS_FLAGS = $(PLATFORM_DEBUG_FLAGS)
 LIBRARY_FLAGS = /noconfig
diff --git a/mcs/build/nunit-summary.xsl b/mcs/build/nunit-summary.xsl
deleted file mode 100644 (file)
index 70972ad..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-<xsl:output method='text'/>
-
-<xsl:template match="/">
-       <xsl:apply-templates/>
-</xsl:template>
-
-<xsl:template match="test-results">
-<xsl:text>Tests run: </xsl:text>
-<xsl:value-of select="@total"/>
-<xsl:text>, Failures: </xsl:text>
-<xsl:value-of select="@failures"/>
-<xsl:text>, Not run: </xsl:text>
-<xsl:value-of select="@not-run"/>
-<xsl:text>, Time: </xsl:text>
-<xsl:value-of select="test-suite/@time"/>
-<xsl:text> seconds
-</xsl:text>
-<xsl:text>
-</xsl:text>
-
-<xsl:if test="//test-suite[failure]"><xsl:text>Test Fixture SetUp Failures:
-</xsl:text></xsl:if>
-<xsl:apply-templates select="//test-suite[failure]"/>
-<xsl:if test="//test-case[failure]"><xsl:text>Test Case Failures:
-</xsl:text></xsl:if>
-<xsl:apply-templates select="//test-case[failure]"/>
-<xsl:if test="//test-case[@executed='False']"><xsl:text>Tests not run:
-</xsl:text></xsl:if>
-<xsl:apply-templates select="//test-case[@executed='False']"/>
-<xsl:text disable-output-escaping='yes'>&#xD;&#xA;</xsl:text>
-</xsl:template>
-
-<xsl:template match="test-case|test-suite">
-       <xsl:value-of select="position()"/><xsl:text>) </xsl:text>
-       <xsl:value-of select="@name"/>
-       <xsl:text> : </xsl:text>
-       <xsl:value-of select="child::node()/message"/>
-<xsl:text disable-output-escaping='yes'>&#xD;&#xA;</xsl:text>
-       <xsl:if test="failure">
-               <xsl:value-of select="failure/stack-trace"/>
-<xsl:text>
-</xsl:text>
-       </xsl:if>
-</xsl:template>
-
-</xsl:stylesheet>
index bed99f53387d0a7b9860fcb5334478d926a22769..4f34c924f03258a9d7c7f0618f0b33c317e31826 100644 (file)
@@ -7,7 +7,7 @@ PLATFORM_DEBUG_FLAGS = /debug+ /debug:full
 PLATFORM_MCS_FLAGS = /nologo
 PLATFORM_RUNTIME = 
 PLATFORM_CORLIB = mscorlib.dll
-PLATFORM_TEST_HARNESS_EXCLUDES =
+PLATFORM_TEST_HARNESS_EXCLUDES = NotOnWindows,
 
 EXTERNAL_MCS = mcs
 EXTERNAL_MBAS = vbc.exe
index d9ff3b67dc9334f4b6727536b33ef219a08db150..bf52c7e791e9ec240a2e4790565f926dc450828a 100644 (file)
@@ -32,7 +32,6 @@ PROFILE_MCS_FLAGS = \
        $(PLATFORM_DEBUG_FLAGS)
 
 FRAMEWORK_VERSION = 2.1
-NUNIT_LITE = yes
 
 # the tuner takes care of the install
 NO_INSTALL = yes
index 1603d123c72bc13c29fa0b6b73e4a782da8bbfb1..ff9e0fd4536182d689f8530b5b40639e5983bfe3 100644 (file)
@@ -31,7 +31,8 @@ PROFILE_MCS_FLAGS = \
        -nowarn:1699 \
        -nostdlib \
        $(DEFAULT_REFERENCES) \
-       $(PLATFORM_DEBUG_FLAGS)
+       $(PLATFORM_DEBUG_FLAGS) \
+       $(MONOTOUCH_MCS_FLAGS)
 
 FRAMEWORK_VERSION = 2.1
 
index 50e8214884dfd91c975de9c1071304447aba3db5..ab1aa6fa0716e6afd0799f5764958fda7cde1e06 100644 (file)
@@ -28,10 +28,13 @@ PROFILE_MCS_FLAGS = \
        -nowarn:1699 \
        -nostdlib \
        $(DEFAULT_REFERENCES) \
-       $(PLATFORM_DEBUG_FLAGS)
+       $(PLATFORM_DEBUG_FLAGS) \
+       $(XAMMAC_MCS_FLAGS)
 
 FRAMEWORK_VERSION = 2.1
 NO_TEST = yes
 NO_INSTALL = yes
 MOBILE_DYNAMIC = yes
 MOBILE_PROFILE = yes
+
+PROFILE_DISABLE_BTLS=1
index 83bfc92fcb26b3dba7f4dac44c22de4506cb0e31..b9881fe64def8d8c9b90731784504d8780795474 100644 (file)
@@ -1,11 +1,14 @@
 include $(topdir)/build/profiles/net_4_x.make
+
 PROFILE_MCS_FLAGS += \
        -d:FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK \
        -d:NO_SYSTEM_DRAWING_DEPENDENCY \
        -d:NO_WINFORMS_DEPENDENCY \
        -d:NO_SYSTEM_WEB_DEPENDENCY \
        -d:XAMMAC_4_5 \
-       -d:XAMARIN_MODERN
+       -d:XAMARIN_MODERN \
+       $(XAMMAC_MCS_FLAGS)
+
 XAMMAC_4_5=1
 NO_WINDOWS_BASE=1
 NO_SYSTEM_WEB_DEPENDENCY=1
@@ -15,3 +18,5 @@ NO_SYSTEM_DRAWING_DEPENDENCY=1
 NO_SYSTEM_SERVICEMODEL_ACTIVATION_DEPENDENCY=1
 NO_SYSTEM_DESIGN_DEPENDENCY=1
 NO_SYSTEM_DIRECTORY_SERVICES_DEPENDENCY=1
+
+PROFILE_DISABLE_BTLS=1
index ac3a476dfb1055fa46cad6cca78fddf90391d007..d25eb35f6e8f9a3510bcb3f2fdd6c527538601b0 100644 (file)
@@ -116,22 +116,6 @@ endif
 
 include $(topdir)/build/profiles/$(PROFILE).make
 
-# If the profile is using nunit-lite, use it
-ifdef NUNIT_LITE
-TEST_HARNESS=$(topdir)/class/lib/$(PROFILE)/nunit-lite-console.exe
-endif
-
-# Make sure propagates
-export TEST_HARNESS
-
-# If the profile is using nunit-lite, use it
-ifdef NUNIT_LITE
-TEST_HARNESS=$(topdir)/class/lib/$(PROFILE)/nunit-lite-console.exe
-endif
-
-# Make sure propagates
-export TEST_HARNESS
-
 ifdef BCL_OPTIMIZE
 PROFILE_MCS_FLAGS += -optimize
 endif
index 749b5a0faf4edbd8d29eb176582e397ec64db32c..d9f6a95ff72b5d1653e3a0f809d994029c3ee5cf 100644 (file)
@@ -19,11 +19,7 @@ TEST_RUNTIME_WRAPPERS_PATH = $(shell dirname $(RUNTIME))/_tmpinst/bin
 ## Unit test support
 ifndef NO_TEST
 
-ifdef NUNIT_LITE
 test_nunit_lib = nunitlite.dll
-else
-test_nunit_lib = nunit.framework.dll nunit.core.dll nunit.util.dll nunit.mocks.dll
-endif
 
 TEST_LIB_MCS_FLAGS = $(patsubst %,-r:$(topdir)/class/lib/$(PROFILE)/%.dll,$(TEST_LIB_REFS))
 
@@ -58,19 +54,11 @@ ifndef NO_TEST
 $(test_nunit_dep): $(topdir)/build/deps/nunit-$(PROFILE).stamp
        @if test -f $@; then :; else rm -f $<; $(MAKE) $<; fi
 
-ifdef NUNIT_LITE
 $(topdir)/build/deps/nunit-$(PROFILE).stamp:
 ifndef PARENT_PROFILE
        cd ${topdir}/tools/nunit-lite && $(MAKE)
 endif
        echo "stamp" >$@
-else
-$(topdir)/build/deps/nunit-$(PROFILE).stamp:
-ifndef PARENT_PROFILE
-       cd ${topdir}/nunit24 && $(MAKE)
-endif
-       echo "stamp" >$@
-endif
 
 tests_CLEAN_FILES += $(topdir)/build/deps/nunit-$(PROFILE).stamp
 endif
@@ -90,52 +78,18 @@ run-test-ondotnet-local: run-test-ondotnet-lib
 TEST_HARNESS_EXCLUDES = -exclude=$(PLATFORM_TEST_HARNESS_EXCLUDES)$(PROFILE_TEST_HARNESS_EXCLUDES)NotWorking,ValueAdd,CAS,InetAccess
 TEST_HARNESS_EXCLUDES_ONDOTNET = /exclude:$(PLATFORM_TEST_HARNESS_EXCLUDES)$(PROFILE_TEST_HARNESS_EXCLUDES)NotDotNet,CAS
 
-ifdef NUNIT_LITE
 NOSHADOW_FLAG =
-NUNIT_XML_FLAG = -format:nunit2 -result:
-OUTPUT_FILE_FLAG=-out
-else
-OUTPUT_FILE_FLAG=-output
-NOSHADOW_FLAG = -noshadow
-NUNIT_XML_FLAG = -xml=
-endif
-
-ifdef NUNIT_LITE
-NOSHADOW_FLAG =
-NUNIT_XML_FLAG = -format:nunit2 -result:
-OUTPUT_FILE_FLAG=-out
-else
-OUTPUT_FILE_FLAG=-output
-NOSHADOW_FLAG = -noshadow
-NUNIT_XML_FLAG = -xml=
-endif
-
-ifdef TEST_HARNESS_VERBOSE
-TEST_HARNESS_OUTPUT = -labels
-TEST_HARNESS_OUTPUT_ONDOTNET = -labels
-TEST_HARNESS_POSTPROC = :
-TEST_HARNESS_POSTPROC_ONDOTNET = :
-else
-TEST_HARNESS_OUTPUT = $(OUTPUT_FILE_FLAG)=TestResult-$(PROFILE).log
-TEST_HARNESS_OUTPUT_ONDOTNET = $(OUTPUT_FILE_FLAG)=TestResult-ondotnet-$(PROFILE).log
-TEST_HARNESS_POSTPROC = (echo ''; cat TestResult-$(PROFILE).log) | sed '1,/^Tests run: /d'; xsltproc $(topdir)/build/nunit-summary.xsl TestResult-$(PROFILE).xml >> TestResult-$(PROFILE).log
-TEST_HARNESS_POSTPROC_ONDOTNET = (echo ''; cat TestResult-ondotnet-$(PROFILE).log) | sed '1,/^Tests run: /d'; xsltproc $(topdir)/build/nunit-summary.xsl TestResult-ondotnet-$(PROFILE).xml >> TestResult-ondotnet-$(PROFILE).log
-endif
 
 ifdef FIXTURE
-ifdef NUNIT_LITE
 FIXTURE_ARG = -test=MonoTests.$(FIXTURE)
-else
-FIXTURE_ARG = -fixture=MonoTests.$(FIXTURE)
-endif
 endif
 
 ifdef TESTNAME
-ifdef NUNIT_LITE
 TESTNAME_ARG = -test=MonoTests.$(TESTNAME)
-else
-TESTNAME_ARG = -run=MonoTests.$(TESTNAME)
 endif
+
+ifdef TEST_HARNESS_VERBOSE
+LABELS_ARG = -labels
 endif
 
 ifdef ALWAYS_AOT
@@ -147,19 +101,30 @@ test-local-aot-compile: $(topdir)/build/deps/nunit-$(PROFILE).stamp
 
 endif # ALWAYS_AOT
 
+NUNITLITE_CONFIG_FILE=$(topdir)/class/lib/$(PROFILE)/$(PARENT_PROFILE)nunit-lite-console.exe.config
+
+patch-nunitlite-appconfig:
+       cp -f $(topdir)/tools/nunit-lite/nunit-lite-console/nunit-lite-console.exe.config.tmpl $(NUNITLITE_CONFIG_FILE)
+ifdef TEST_NUNITLITE_APP_CONFIG_GLOBAL
+       sed -i -e "/__INSERT_CUSTOM_APP_CONFIG_GLOBAL__/r $(TEST_NUNITLITE_APP_CONFIG_GLOBAL)" $(NUNITLITE_CONFIG_FILE)
+endif
+ifdef TEST_NUNITLITE_APP_CONFIG_RUNTIME
+       sed -i -e "/__INSERT_CUSTOM_APP_CONFIG_RUNTIME__/r $(TEST_NUNITLITE_APP_CONFIG_RUNTIME)" $(NUNITLITE_CONFIG_FILE)
+endif
+
 ## FIXME: i18n problem in the 'sed' command below
-run-test-lib: test-local test-local-aot-compile
+run-test-lib: test-local test-local-aot-compile patch-nunitlite-appconfig
        ok=:; \
-       PATH="$(TEST_RUNTIME_WRAPPERS_PATH):$(PATH)" MONO_REGISTRY_PATH="$(HOME)/.mono/registry" MONO_TESTS_IN_PROGRESS="yes" $(TEST_RUNTIME) $(RUNTIME_FLAGS) $(AOT_RUN_FLAGS) $(TEST_HARNESS) $(test_assemblies) $(NOSHADOW_FLAG) $(TEST_HARNESS_FLAGS) $(LOCAL_TEST_HARNESS_FLAGS) $(TEST_HARNESS_EXCLUDES) $(TEST_HARNESS_OUTPUT) $(NUNIT_XML_FLAG)TestResult-$(PROFILE).xml $(FIXTURE_ARG) $(TESTNAME_ARG)|| ok=false; \
+       PATH="$(TEST_RUNTIME_WRAPPERS_PATH):$(PATH)" MONO_REGISTRY_PATH="$(HOME)/.mono/registry" MONO_TESTS_IN_PROGRESS="yes" $(TEST_RUNTIME) $(RUNTIME_FLAGS) $(AOT_RUN_FLAGS) $(TEST_HARNESS) $(test_assemblies) $(NOSHADOW_FLAG) $(TEST_HARNESS_FLAGS) $(LOCAL_TEST_HARNESS_FLAGS) $(TEST_HARNESS_EXCLUDES) $(LABELS_ARG) -format:nunit2 -result:TestResult-$(PROFILE).xml $(FIXTURE_ARG) $(TESTNAME_ARG)|| ok=false; \
        if [ ! -f "TestResult-$(PROFILE).xml" ]; then echo "<?xml version='1.0' encoding='utf-8'?><test-results failures='1' total='1' not-run='0' name='bcl-tests' date='$$(date +%F)' time='$$(date +%T)'><test-suite name='$(strip $(test_assemblies))' success='False' time='0'><results><test-case name='crash' executed='True' success='False' time='0'><failure><message>The test runner didn't produce a test result XML, probably due to a crash of the runtime. Check the log for more details.</message><stack-trace></stack-trace></failure></test-case></results></test-suite></test-results>" > TestResult-$(PROFILE).xml; fi; \
-       $(TEST_HARNESS_POSTPROC) ; $$ok
+       $$ok
 
 ## Instructs compiler to compile to target .net execution, it can be usefull in rare cases when runtime detection is not possible
 run-test-ondotnet-lib: LOCAL_TEST_COMPILER_ONDOTNET_FLAGS:=-d:RUN_ONDOTNET
 run-test-ondotnet-lib: test-local
        ok=:; \
-       $(TEST_HARNESS) $(test_assemblies) $(NOSHADOW_FLAG) $(TEST_HARNESS_FLAGS) $(LOCAL_TEST_HARNESS_ONDOTNET_FLAGS) $(TEST_HARNESS_EXCLUDES_ONDOTNET) $(TEST_HARNESS_OUTPUT_ONDOTNET) $(NUNIT_XML_FLAG)=TestResult-ondotnet-$(PROFILE).xml $(FIXTURE_ARG) $(TESTNAME_ARG) || ok=false; \
-       $(TEST_HARNESS_POSTPROC_ONDOTNET) ; $$ok
+       $(TEST_HARNESS) $(test_assemblies) $(NOSHADOW_FLAG) $(TEST_HARNESS_FLAGS) $(LOCAL_TEST_HARNESS_ONDOTNET_FLAGS) $(TEST_HARNESS_EXCLUDES_ONDOTNET) $(LABELS_ARG) -format:nunit2 -result:TestResult-ondotnet-$(PROFILE).xml $(FIXTURE_ARG) $(TESTNAME_ARG) || ok=false; \
+       $$ok
 
 
 endif # test_assemblies
@@ -194,3 +159,4 @@ $(test_makefrag): $(test_response)
 
 endif
 
+.PHONY: patch-nunitlite-appconfig
index bfa54497303dd9f053607961cff2b346d3bd9914..887bc47e19e6fedb2d06eb6df82549e2057181ff 100644 (file)
@@ -1 +1,2 @@
 /Test/resources/*.proj
+Test/test-config-file-*
index 9aed81206542d94d4976f0974107b89d405a8e89..9acd2e184d4f86e78a2d743390492616e53a54b8 100644 (file)
@@ -12,6 +12,7 @@ LIB_MCS_FLAGS =
 
 TEST_MCS_FLAGS =
 TEST_LIB_REFS = $(XBUILD_FRAMEWORK) $(XBUILD_UTILITIES) $(PARENT_PROFILE)System.Xml
+TEST_NUNITLITE_APP_CONFIG_RUNTIME=Test/test-config-file-$(PROFILE)
 
 EXTRA_DISTFILES = \
        Test/resources/TestTasks.cs             \
diff --git a/mcs/class/Microsoft.Build.Framework/.gitignore b/mcs/class/Microsoft.Build.Framework/.gitignore
new file mode 100644 (file)
index 0000000..c8cb717
--- /dev/null
@@ -0,0 +1 @@
+Test/test-config-file-*
index f31f5a5835ea5f0b8f33c7bdfc059a0490a3e8e9..edd7cc2e8eb7477e19cadd28edf7e759084d932b 100644 (file)
@@ -10,6 +10,8 @@ LIBRARY = Microsoft.Build.Framework.dll
 LIB_REFS = $(PARENT_PROFILE)System
 LIB_MCS_FLAGS =
 
+TEST_NUNITLITE_APP_CONFIG_RUNTIME=Test/test-config-file-$(PROFILE)
+
 EXTRA_DISTFILES = \
        Mono.XBuild.Framework/AssemblyLoadInfo.cs
 
index bfa54497303dd9f053607961cff2b346d3bd9914..887bc47e19e6fedb2d06eb6df82549e2057181ff 100644 (file)
@@ -1 +1,2 @@
 /Test/resources/*.proj
+Test/test-config-file-*
index d451c754e74471c627da9bbd3e6ffd86fd871a90..a919129b083e53916526a0ea1316dc6f313f5771 100644 (file)
@@ -15,6 +15,8 @@ LIB_REFS = $(PARENT_PROFILE)System $(PARENT_PROFILE)System.Core $(PARENT_PROFILE
 TEST_MCS_FLAGS =
 TEST_LIB_REFS = $(PARENT_PROFILE)System.Xml $(XBUILD_ENGINE) $(XBUILD_FRAMEWORK) $(XBUILD_TASKS) $(XBUILD_UTILITIES) $(PARENT_PROFILE)System.Core
 
+TEST_NUNITLITE_APP_CONFIG_RUNTIME=Test/test-config-file-$(PROFILE)
+
 ifeq (4, $(FRAMEWORK_VERSION_MAJOR))
 TEST_LIB_REFS += Microsoft.Build
 endif
@@ -23,8 +25,7 @@ EXTRA_DISTFILES = \
        Test/resources/test.cs \
        Test/resources/Sample.cs \
        Test/resources/Sample.vb \
-       Test/resources/junk.txt \
-       Test/test-config-file*
+       Test/resources/junk.txt
 
 Test/resources/test.dll: Test/resources/test.cs
        $(CSCOMPILE) -target:library /out:$@ $<
diff --git a/mcs/class/Microsoft.Build.Tasks/Test/test-config-file-net-4.0 b/mcs/class/Microsoft.Build.Tasks/Test/test-config-file-net-4.0
deleted file mode 100644 (file)
index 3c78f3b..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version ="1.0"?>
-<configuration>
-    <runtime>
-        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-            <dependentAssembly>
-                <assemblyIdentity name="Microsoft.Build.Framework" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
-                <bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="4.0.0.0"/>
-            </dependentAssembly>
-            <dependentAssembly>
-                <assemblyIdentity name="Microsoft.Build.Engine" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
-                <bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="4.0.0.0"/>
-            </dependentAssembly>
-        </assemblyBinding>
-    </runtime>
-</configuration>
diff --git a/mcs/class/Microsoft.Build.Utilities/.gitignore b/mcs/class/Microsoft.Build.Utilities/.gitignore
new file mode 100644 (file)
index 0000000..c8cb717
--- /dev/null
@@ -0,0 +1 @@
+Test/test-config-file-*
index 10ef6780d4af6caf04ee40b279df2c40a3915ad6..2c644346e2c34c2c75740bf4afe1b75e8a88ec8c 100644 (file)
@@ -15,6 +15,7 @@ TEST_RESX_RESOURCES = Test/Microsoft.Build.Utilities/Strings.resources
 
 TEST_LIB_REFS = $(XBUILD_ENGINE) $(XBUILD_FRAMEWORK) $(PARENT_PROFILE)System $(PARENT_PROFILE)System.Core
 TEST_MCS_FLAGS = $(TEST_RESX_RESOURCES:%=-resource:%)
+TEST_NUNITLITE_APP_CONFIG_RUNTIME=Test/test-config-file-$(PROFILE)
 
 include $(XBUILD_DIR)/xbuild_test.make
 include ../../build/library.make
index bc686cf9c839b693f7644e676abd2e75019cdb96..07547b0fc205a26531398ebc34e43439b95ec841 100644 (file)
@@ -6,3 +6,4 @@ bin/
 Microsoft.Build.Internal/ExpressionParser.cs
 Microsoft.Build.Internal/y.output
 Test/FunctionalTestProject*.csproj
+Test/test-config-file-*
index 933782ff268b64d48a5d746d2223c93ffee7d39c..47e9cf9ad41454df2b1fd684577509b0d82cc6b6 100644 (file)
@@ -10,9 +10,10 @@ LIBRARY = Microsoft.Build.dll
 LIB_REFS = $(PARENT_PROFILE)System $(PARENT_PROFILE)System.Core $(PARENT_PROFILE)System.Xml Microsoft.Build.Engine Microsoft.Build.Framework
 LIB_MCS_FLAGS = \
        /d:MICROSOFT_BUILD_DLL
-       
+
 TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
 TEST_LIB_REFS = $(XBUILD_UTILITIES)
+TEST_NUNITLITE_APP_CONFIG_RUNTIME=Test/test-config-file-$(PROFILE)
 
 EXTRA_DISTFILES = \
        Microsoft.Build.Internal/ExpressionParser.jay   \
index 322006a4e849fadd25b24ad978fb62530d9fe27e..135734fb03064cb7c699bdb5d5281abc22897e7f 100644 (file)
@@ -80,6 +80,9 @@ namespace Microsoft.Build.Internal
                                        if (!queued_builds.TryDequeue (out build))
                                                continue;
                                        StartOneBuild (build);
+                               } catch (ThreadAbortException) {
+                                       // do nothing
+                                       break;
                                } catch (Exception ex) {
                                        // FIXME: I guess INodeLogger should be used instead.
                                        Console.Error.WriteLine ("Uncaught build node exception occured");
index 7b65749c86afd94b360d4eb80d6e619590998359..28c4af1277abbcb7a31cdd66a5310bc2b315498b 100644 (file)
@@ -1,3 +1,4 @@
+../../test-helpers/NunitHelpers.cs
 FunctionalTest.cs
 Microsoft.Build.Construction/ProjectItemElementTest.cs
 Microsoft.Build.Construction/ProjectRootElementTest.cs
index 984809180a1ea283051576f8071c219b890182a5..9e77c38bdf12f6e1000da5833db06f75588354cc 100644 (file)
@@ -1,2 +1,3 @@
+../../test-helpers/NunitHelpers.cs
 RewriteAndLoad.cs
 TestCCRewrite.cs
index 89763f52ec9185327ba7f17d63a6ffc14e349b6e..816fb68dc5fc3bcbc9fb8669317cfd8e68fb3166 100644 (file)
@@ -187,13 +187,54 @@ namespace Mono.CompilerServices.SymbolWriter
                public void DefineMethod (MonoSymbolFile file, int token)
                {
                        var blocks = Blocks;
+                       if (blocks.Length > 0) {
+                               //
+                               // When index is provided by user it can be inserted in
+                               // any order but mdb format does not store its value. It
+                               // uses stored order as the index instead.
+                               //
+                               var sorted = new List<CodeBlockEntry> (blocks.Length);
+                               int max_index = 0;
+                               for (int i = 0; i < blocks.Length; ++i) {
+                                       max_index = System.Math.Max (max_index, blocks [i].Index);
+                               }
+
+                               for (int i = 0; i < max_index; ++i) {
+                                       var scope_index = i + 1;
+
+                                       //
+                                       // Common fast path
+                                       //
+                                       if (i < blocks.Length && blocks [i].Index == scope_index) {
+                                               sorted.Add (blocks [i]);
+                                               continue;
+                                       }
+
+                                       bool found = false;
+                                       for (int ii = 0; ii < blocks.Length; ++ii) {
+                                               if (blocks [ii].Index == scope_index) {
+                                                       sorted.Add (blocks [ii]);
+                                                       found = true;
+                                                       break;
+                                               }
+                                       }
+
+                                       if (found)
+                                               continue;
+
+                                       //
+                                       // Ideally this should never happen but with current design we can
+                                       // generate scope index for unreachable code before reachable code
+                                       //
+                                       sorted.Add (new CodeBlockEntry (scope_index, -1, CodeBlockEntry.Type.CompilerGenerated, 0));
+                               }
 
-                       //
-                       // When index is provided by user it can be inserted in
-                       // any order but mdb format does not store its value. It
-                       // uses store order instead as the index.
-                       //
-                       Array.Sort (blocks, (x, y) => x.Index.CompareTo (y.Index));
+                               blocks = sorted.ToArray ();
+                               //for (int i = 0; i < blocks.Length; ++i) {
+                               //      if (blocks [i].Index - 1 != i)
+                               //                      throw new ArgumentException ("CodeBlocks cannot be converted to mdb format");
+                               //}
+                       }
 
                        var entry = new MethodEntry (
                                file, _comp_unit.Entry, token, ScopeVariables,
index 1eb8276dbde5a7eae4bf842def1b68edff5afaea..c187abfe371c2a2309625f06d481169d4f1a32b7 100644 (file)
@@ -1,3 +1,4 @@
+../../test-helpers/NunitHelpers.cs
 Mono.Collections.Concurrent/CollectionStressTestHelper.cs
 Mono.Collections.Concurrent/ConcurrentSkipListTests.cs
 Mono.Threading/ParallelTestHelper.cs
index a2f290f8656ed6bd2f002f6c1d1f468e9007ea15..55773333f78b9a554cc45b94c2698868d4f26fdf 100644 (file)
@@ -1,3 +1,4 @@
+../../test-helpers/NunitHelpers.cs
 Mono.Unix/ReadlinkTest.cs
 Mono.Unix/StdioFileStreamTest.cs
 Mono.Unix/UnixEncodingTest.cs
index f68fe53b8ce70b896dbb603a9530042fddae1885..892f087e48f9b00aa3dbefa0b306c454c522fe91 100644 (file)
@@ -8,9 +8,7 @@
 //
 
 using NUnit.Framework;
-#if !MONODROID
-using NUnit.Framework.SyntaxHelpers;
-#endif
+
 using System;
 using System.Text;
 using System.Threading;
@@ -21,7 +19,7 @@ using Mono.Unix.Native;
 namespace MonoTests.Mono.Unix.Native {
 
        [TestFixture]
-       [Category ("NotOnMac")]
+       [Category ("NotOnMac"), Category ("NotOnWindows")]
        public class RealTimeSignumTest 
        {
                [Test]
index 3ec10f916cebc48da8f46d660c50e2baf61dd1fd..31c4549dd6e2a3e8a269eafd6b4c6e7d880a4c3c 100644 (file)
@@ -20,7 +20,7 @@ using NUnit.Framework;
 
 namespace MonoTests.Mono.Unix.Native
 {
-       [TestFixture, Category ("NotDotNet")]
+       [TestFixture, Category ("NotDotNet"), Category ("NotOnWindows")]
        public class SocketTest {
 
                string TempFolder;
index 1b7b77d5aca4704f5ff51304098543516268bfb2..aa0c06b76c61b87b2f76f222457d2069badf59ac 100644 (file)
@@ -17,7 +17,7 @@ using Mono.Unix.Native;
 
 namespace MonoTests.Mono.Unix.Native {
 
-       [TestFixture]
+       [TestFixture, Category ("NotOnWindows")]
        public class StdlibTest
        {
                private class SignalTest {
index 608127b568c81272027312ca22a7629841e02e3a..2f286d49b8193765c9f2cbd57c432e7b0c0e857d 100644 (file)
@@ -18,7 +18,7 @@ using NUnit.Framework;
 
 namespace MonoTests.Mono.Unix
 {
-       [TestFixture, Category ("NotDotNet")]
+       [TestFixture, Category ("NotDotNet"), Category ("NotOnWindows")]
        public class ReadlinkTest {
 
                static string[] Targets = {
@@ -173,7 +173,7 @@ namespace MonoTests.Mono.Unix
                                        long r = Syscall.readlink (link, buf);
                                        if (r < 0)
                                                UnixMarshal.ThrowExceptionForLastError ();
-                                       Assert.GreaterOrEqual (buf.Length, r);
+                                       AssertHelper.GreaterOrEqual (buf.Length, r);
                                        if (r == buf.Length)
                                                buf = new byte[checked (buf.Length * 2)];
                                        else
@@ -199,7 +199,7 @@ namespace MonoTests.Mono.Unix
                                        long r = Syscall.readlinkat (TempFD, "link", buf);
                                        if (r < 0)
                                                UnixMarshal.ThrowExceptionForLastError ();
-                                       Assert.GreaterOrEqual (buf.Length, r);
+                                       AssertHelper.GreaterOrEqual (buf.Length, r);
                                        if (r == buf.Length)
                                                buf = new byte[checked (buf.Length * 2)];
                                        else
@@ -226,7 +226,7 @@ namespace MonoTests.Mono.Unix
                                        if (r < 0)
                                                UnixMarshal.ThrowExceptionForLastError ();
                                        Assert.AreEqual (r, sb.Length);
-                                       Assert.GreaterOrEqual (sb.Capacity, r);
+                                       AssertHelper.GreaterOrEqual (sb.Capacity, r);
                                        if (r == sb.Capacity)
                                                checked { sb.Capacity *= 2; }
                                        else
@@ -255,7 +255,7 @@ namespace MonoTests.Mono.Unix
                                        if (r < 0)
                                                UnixMarshal.ThrowExceptionForLastError ();
                                        Assert.AreEqual (r, sb.Length);
-                                       Assert.GreaterOrEqual (sb.Capacity, r);
+                                       AssertHelper.GreaterOrEqual (sb.Capacity, r);
                                        if (r == sb.Capacity)
                                                checked { sb.Capacity *= 2; }
                                        else
index 21e5b791636f6aa6da1e6b9b3a9ce0091155cadd..837fe4ec26309bc7fb336de4165c57cc263700e5 100644 (file)
@@ -17,7 +17,7 @@ using Mono.Unix;
 
 namespace MonoTests.Mono.Unix {
 
-    [TestFixture]
+    [TestFixture, Category ("NotOnWindows")]
     public class UnixEndPointTest {
 
         // Regression test for https://bugzilla.xamarin.com/show_bug.cgi?id=35004
index 81e775e64b0d517b962928b2b4bd04301390aabf..da6bbe083723479f7d3e4bcb9a1ac199d2f6fe4c 100644 (file)
@@ -21,7 +21,7 @@ using Syscall = Mono.Unix.Native.Syscall;
 
 namespace MonoTests.Mono.Unix {
 
-       [TestFixture, Category ("NotDotNet")]
+       [TestFixture, Category ("NotDotNet"), Category ("NotOnWindows")]
        public class UnixGroupTest
        {
                [Test]
index b2312b5590fe9751ff1a8c42f15d92a2779aa50e..ad2d3089a42918407f930f779c260b40774e3cb3 100644 (file)
@@ -14,7 +14,7 @@ using Mono.Unix;
 
 namespace MonoTests.Mono.Unix {
 
-    [TestFixture]
+    [TestFixture, Category ("NotOnWindows")]
     public class UnixListenerTest {
 
         // test that a socket file is created and deleted by the UnixListener
index e27a5dd246c68ef04c4f602b6fda95195e4f69aa..8ae50b98c977fa9af5531e7dbae9227c8d8586cd 100644 (file)
@@ -28,7 +28,7 @@ namespace MonoTests.Mono.Unix {
                }
        }
 
-       [TestFixture]
+       [TestFixture, Category ("NotOnWindows")]
        public class UnixMarshalTest {
 #if false
                public static void Main ()
index c21348748dcbace4ecaa98b58e0591dfa6012e5a..6c10225dfe72a0876dd329f2c97b98121c00f9ce 100644 (file)
@@ -16,7 +16,7 @@ using Mono.Unix;
 namespace MonoTests.Mono.Unix
 {
 
-       [TestFixture, Category ("NotDotNet")]
+       [TestFixture, Category ("NotDotNet"), Category ("NotOnWindows")]
        public class UnixPathTest {
 
                private static readonly char DSC = UnixPath.DirectorySeparatorChar;
index 9abc27094c9d0fe4c8fb8610e8b767386a4e0e8e..5dc422d5a344aba7e90b92009d455925ed63dd0d 100644 (file)
@@ -8,21 +8,17 @@
 //
 
 using NUnit.Framework;
-#if !MONODROID
-using NUnit.Framework.SyntaxHelpers;
-#endif
+
 using System;
 using System.Text;
 using System.Threading;
 using Mono.Unix;
 using Mono.Unix.Android;
 using Mono.Unix.Native;
-#if !MONODROID
-namespace NUnit.Framework.SyntaxHelpers { class Dummy {} }
-#endif
+
 namespace MonoTests.Mono.Unix {
 
-       [TestFixture]
+       [TestFixture, Category ("NotOnWindows")]
        public class UnixSignalTest {
 
                // helper method to create a thread waiting on a UnixSignal
index 30f0450637ca6e68faa464296628120ee4abfd73..68a36c935c67f09a1217056961986a3762a9be67 100644 (file)
@@ -21,7 +21,7 @@ using Syscall = Mono.Unix.Native.Syscall;
 
 namespace MonoTests.Mono.Unix {
 
-       [TestFixture, Category ("NotDotNet")]
+       [TestFixture, Category ("NotDotNet"), Category ("NotOnWindows")]
        public class UnixUserTest
        {
                [Test]
index ae7afa670cb5380ad33e9656aace557e13adde50..aa931ee9db789b334cb89012a555eff52bc07c37 100644 (file)
@@ -3,7 +3,7 @@ SUBDIRS =
 include ../../build/rules.make
 
 LIBRARY = Mono.Reactive.Testing.dll
-LIB_REFS = System System.Core System.Reactive.Interfaces System.Reactive.Core System.Reactive.Linq System.Reactive.PlatformServices System.Reactive.Providers System.Reactive.Runtime.Remoting System.Reactive.Experimental System.Reactive.Windows.Forms System.Reactive.Windows.Threading System.Reactive.Observable.Aliases System.Windows.Forms WindowsBase nunit.framework
+LIB_REFS = System System.Core System.Reactive.Interfaces System.Reactive.Core System.Reactive.Linq System.Reactive.PlatformServices System.Reactive.Providers System.Reactive.Runtime.Remoting System.Reactive.Experimental System.Reactive.Windows.Forms System.Reactive.Windows.Threading System.Reactive.Observable.Aliases System.Windows.Forms WindowsBase nunitlite
 LIB_MCS_FLAGS = \
                @more_build_args \
                -d:NUNIT -d:MONO -d:DESKTOPCLR
index 0ad21f2c4362fb069ea223c73805ebcfc041e0e6..6557bccc3e565b4202e2633eb30aa84b50b263cc 100644 (file)
@@ -2,7 +2,7 @@ thisdir = class/Mono.Security/Test/tools/sockethell
 SUBDIRS = 
 include ../../../../../build/rules.make
 
-LOCAL_MCS_FLAGS = -r:System.dll -r:Mono.Security.dll -r:../../../../lib/net_4_x/nunit.framework.dll
+LOCAL_MCS_FLAGS = -r:System.dll -r:Mono.Security.dll -r:../../../../lib/net_4_x/nunitlite.dll
 
 all-local install-local uninstall-local:
 
diff --git a/mcs/class/Mono.XBuild.Tasks/.gitignore b/mcs/class/Mono.XBuild.Tasks/.gitignore
new file mode 100644 (file)
index 0000000..c8cb717
--- /dev/null
@@ -0,0 +1 @@
+Test/test-config-file-*
index 8d50c7ad6294d7f8c10c527a4b39005e1c272e01..11f7b791c432538d4dfaff4ee48fd22745c6fe20 100644 (file)
@@ -10,6 +10,8 @@ LIBRARY = Mono.XBuild.Tasks.dll
 LIB_REFS = $(PARENT_PROFILE)System $(PARENT_PROFILE)System.Xml
 LIB_MCS_FLAGS =
 
+TEST_NUNITLITE_APP_CONFIG_RUNTIME=Test/test-config-file-$(PROFILE)
+
 include $(XBUILD_DIR)/xbuild_test.make
 
 include ../../build/library.make
index 0dbb1260ba9b06120690e6ce8b91397243621c1c..902f1ac16296e1358a959ce77aca605e4cbe1ade 100644 (file)
@@ -1 +1,2 @@
+../../test-helpers/NunitHelpers.cs
 Mono.XBuild.Tasks/PcFileCacheTest.cs
index 7cdf1b26842530f14994900c373c071a139c4e9c..e6f48050a99ed2acf322ac2d6d3ce25cb37d1eab 100644 (file)
@@ -10,6 +10,7 @@ LIB_REFS = secxml/System bare/System.Xml System.Security
 LIB_MCS_FLAGS = -nowarn:618
 TEST_MCS_FLAGS =
 TEST_LIB_REFS = System.Xml System
+TEST_NUNITLITE_APP_CONFIG_GLOBAL=Test/test-config-file
 
 include ../../build/library.make
 
@@ -20,6 +21,9 @@ configuration_library_deps = \
 
 $(build_lib): $(configuration_library_deps)
 
+test-local:
+       cp Test/appSettings.config $(dir $(NUNITLITE_CONFIG_FILE))/Test-appSettings.config
+
 .NOTPARALLEL: $(configuration_library_deps)
 
 $(secxml_libdir)/System.dll:
diff --git a/mcs/class/System.Configuration/Test/App.config b/mcs/class/System.Configuration/Test/App.config
deleted file mode 100644 (file)
index d07b4f8..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<configuration>
-       <connectionStrings>
-               <add name="test-connstring"
-                       connectionString="Server=(local);Initial Catalog=someDb;User Id=someUser;Password=somePassword;Application Name=someAppName;Min Pool Size=5;Max Pool Size=500;Connect Timeout=10;Connection Lifetime=29;" />
-       </connectionStrings>
-  <appSettings file="Test/appSettings.config" />
-</configuration>
index 83e87e21b6a4deb891818d1ec5744fb290ba6d44..f0445810330c81bf312037684e889cf54e50d30a 100644 (file)
@@ -65,9 +65,9 @@ namespace MonoTests.System.Configuration
                {
                        Directory.SetCurrentDirectory (tempFolder);
 
-                       var currentAssembly = Assembly.GetExecutingAssembly ().Location;
+                       var currentAssembly = TestUtil.ThisApplicationPath;
                        var config = ConfigurationManager.OpenExeConfiguration (currentAssembly);
-                       Assert.AreEqual ("Test/appSettings.config", config.AppSettings.File, "#A01");
+                       Assert.AreEqual ("Test-appSettings.config", config.AppSettings.File, "#A01");
                        Assert.AreEqual ("foo", ConfigurationSettings.AppSettings["TestKey1"], "#A02");
                        Assert.AreEqual ("bar", ConfigurationSettings.AppSettings["TestKey2"], "#A03");
                }
index 7efff1dddffcf879f53a0a534b24cded54d0a213..0b5b3cde0dc1117329452266bc424283f5e90573 100644 (file)
@@ -257,10 +257,9 @@ namespace MonoTests.System.Configuration {
                [Test]
                public void exePath_UserLevelNone ()
                {
-                       string basedir = AppDomain.CurrentDomain.BaseDirectory;
-                       string name = TestUtil.ThisDllName;
+                       string name = TestUtil.ThisApplicationPath;
                        SysConfig config = ConfigurationManager.OpenExeConfiguration (name);
-                       Assert.AreEqual (Path.Combine (basedir, name + ".config"), config.FilePath);
+                       Assert.AreEqual (TestUtil.ThisApplicationPath + ".config", config.FilePath);
                }
 
                [Test]
@@ -615,11 +614,6 @@ namespace MonoTests.System.Configuration {
                [Test]
                public void TestConnectionStringRetrieval ()
                {
-                       var currentAssembly = Assembly.GetExecutingAssembly().Location;
-                       Assert.IsTrue (File.Exists (currentAssembly + ".config"),
-                                      String.Format ("This test cannot succeed without the .config file being in the same place as the assembly ({0})",
-                                                     currentAssembly));
-
                        var connStringObj = ConfigurationManager.ConnectionStrings ["test-connstring"];
                        Assert.IsNotNull (connStringObj);
                        var connString = connStringObj.ConnectionString;
index 4d0e369b414a45eebbdad975446df6e8e7c584f7..2bb7723f7a0dc37d6d8e8f64c455b583a10ce16f 100644 (file)
@@ -37,7 +37,6 @@ using SysConfig = System.Configuration.Configuration;
 
 using NUnit.Framework;
 using NUnit.Framework.Constraints;
-using NUnit.Framework.SyntaxHelpers;
 
 namespace MonoTests.System.Configuration {
        using Util;
index 6faeba67a14b2212d74a2b3643828c129d7678ee..497a8a8081da1ee056ebed31b4bb34427ee2c5b3 100644 (file)
@@ -64,17 +64,16 @@ namespace MonoTests.System.Configuration.Util {
                        }
                }
 
-               public static string ThisDllName {
+               public static string ThisApplicationPath {
                        get {
-                               var asm = Assembly.GetCallingAssembly ();
-                               return Path.GetFileName (asm.Location);
+                               var asm = Assembly.GetEntryAssembly ();
+                               return asm.Location;
                        }
                }
 
                public static string ThisConfigFileName {
                        get {
-                               var asm = Assembly.GetCallingAssembly ();
-                               var exe = Path.GetFileName (asm.Location);
+                               var exe = Path.GetFileName (ThisApplicationPath);
                                return exe + ".config";
                        }
                }
diff --git a/mcs/class/System.Configuration/Test/test-config-file b/mcs/class/System.Configuration/Test/test-config-file
new file mode 100644 (file)
index 0000000..5920c6c
--- /dev/null
@@ -0,0 +1,5 @@
+       <connectionStrings>
+               <add name="test-connstring"
+                       connectionString="Server=(local);Initial Catalog=someDb;User Id=someUser;Password=somePassword;Application Name=someAppName;Min Pool Size=5;Max Pool Size=500;Connect Timeout=10;Connection Lifetime=29;" />
+       </connectionStrings>
+  <appSettings file="Test-appSettings.config" />
diff --git a/mcs/class/System.Configuration/net_4_x_System.Configuration_test.dll.config b/mcs/class/System.Configuration/net_4_x_System.Configuration_test.dll.config
deleted file mode 100644 (file)
index d07b4f8..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<configuration>
-       <connectionStrings>
-               <add name="test-connstring"
-                       connectionString="Server=(local);Initial Catalog=someDb;User Id=someUser;Password=somePassword;Application Name=someAppName;Min Pool Size=5;Max Pool Size=500;Connect Timeout=10;Connection Lifetime=29;" />
-       </connectionStrings>
-  <appSettings file="Test/appSettings.config" />
-</configuration>
index f165f3f62796abe4f1b545373fa8790efda7696f..e48161a358af4bccd8f1119cab6092ebebe55df3 100644 (file)
@@ -44,6 +44,10 @@ namespace Microsoft.Win32.SafeHandles
                        Initialize ((ulong)size);
                }
 
+               internal void Flush () {
+                       MemoryMapImpl.Flush (this.mmap_handle);
+               }
+
                protected override bool ReleaseHandle () {
                        if (this.handle != (IntPtr) (-1))
                                return MemoryMapImpl.Unmap (this.mmap_handle);
index fbc55fd73b5e62c356363f97aeb51b14fe2dbdc8..7a3cce164f61e2feffc9b46fcd751d1c75626e91 100644 (file)
@@ -70,7 +70,7 @@ namespace System.IO.MemoryMappedFiles
                        case 1:
                                return new ArgumentException ("A positive capacity must be specified for a Memory Mapped File backed by an empty file.");
                        case 2:
-                               return new ArgumentOutOfRangeException ("The capacity may not be smaller than the file size.");
+                               return new ArgumentOutOfRangeException ("capacity", "The capacity may not be smaller than the file size.");
                        case 3:
                                return new FileNotFoundException (path);
                        case 4:
@@ -85,6 +85,10 @@ namespace System.IO.MemoryMappedFiles
                                return new ArgumentException ("Invalid FileMode value.");
                        case 9:
                                return new IOException ("Could not map file");
+                       case 10:
+                               return new UnauthorizedAccessException ("Access to the path is denied.");
+                       case 11:
+                               return new ArgumentOutOfRangeException ("capacity", "The capacity cannot be greater than the size of the system's logical address space.");
                        default:
                                return new IOException ("Failed with unknown error code " + error);
                        }
@@ -140,7 +144,7 @@ namespace System.IO.MemoryMappedFiles
                        if (mode == FileMode.Append)
                                throw new ArgumentException ("mode");
 
-                       IntPtr handle = MemoryMapImpl.OpenFile (path, mode, null, out capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages);
+                       IntPtr handle = MemoryMapImpl.OpenFile (path, mode, null, out capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None);
 
                        return new MemoryMappedFile () {
                                handle = handle,
@@ -172,7 +176,7 @@ namespace System.IO.MemoryMappedFiles
                        if (capacity < 0)
                                throw new ArgumentOutOfRangeException ("capacity");
 
-                       IntPtr handle = MemoryMapImpl.OpenFile (path, mode, mapName, out capacity, access, MemoryMappedFileOptions.DelayAllocatePages);
+                       IntPtr handle = MemoryMapImpl.OpenFile (path, mode, mapName, out capacity, access, MemoryMappedFileOptions.None);
                        
                        return new MemoryMappedFile () {
                                handle = handle,
@@ -193,7 +197,7 @@ namespace System.IO.MemoryMappedFiles
                        if ((!MonoUtil.IsUnix && capacity == 0 && fileStream.Length == 0) || (capacity > fileStream.Length))
                                throw new ArgumentException ("capacity");
 
-                       IntPtr handle = MemoryMapImpl.OpenHandle (fileStream.SafeFileHandle.DangerousGetHandle (), mapName, out capacity, access, MemoryMappedFileOptions.DelayAllocatePages);
+                       IntPtr handle = MemoryMapImpl.OpenHandle (fileStream.SafeFileHandle.DangerousGetHandle (), mapName, out capacity, access, MemoryMappedFileOptions.None);
                        
                        MemoryMapImpl.ConfigureHandleInheritability (handle, inheritability);
                                
@@ -220,7 +224,7 @@ namespace System.IO.MemoryMappedFiles
                        if ((!MonoUtil.IsUnix && capacity == 0 && fileStream.Length == 0) || (capacity > fileStream.Length))
                                throw new ArgumentException ("capacity");
 
-                       IntPtr handle = MemoryMapImpl.OpenHandle (fileStream.SafeFileHandle.DangerousGetHandle (), mapName, out capacity, access, MemoryMappedFileOptions.DelayAllocatePages);
+                       IntPtr handle = MemoryMapImpl.OpenHandle (fileStream.SafeFileHandle.DangerousGetHandle (), mapName, out capacity, access, MemoryMappedFileOptions.None);
                        
                        MemoryMapImpl.ConfigureHandleInheritability (handle, inheritability);
                                
@@ -258,13 +262,13 @@ namespace System.IO.MemoryMappedFiles
                [MonoLimitation ("Named mappings scope is process local")]
                public static MemoryMappedFile CreateNew (string mapName, long capacity)
                {
-                       return CreateNew (mapName, capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, null, HandleInheritability.None);
+                       return CreateNew (mapName, capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, null, HandleInheritability.None);
                }
 
                [MonoLimitation ("Named mappings scope is process local")]
                public static MemoryMappedFile CreateNew (string mapName, long capacity, MemoryMappedFileAccess access) 
                {
-                       return CreateNew (mapName, capacity, access, MemoryMappedFileOptions.DelayAllocatePages, null, HandleInheritability.None);
+                       return CreateNew (mapName, capacity, access, MemoryMappedFileOptions.None, null, HandleInheritability.None);
                }
 
                [MonoLimitation ("Named mappings scope is process local; options is ignored")]
@@ -290,7 +294,7 @@ namespace System.IO.MemoryMappedFiles
                [MonoLimitation ("Named mappings scope is process local")]
                public static MemoryMappedFile CreateOrOpen (string mapName, long capacity, MemoryMappedFileAccess access)
                {
-                       return CreateOrOpen (mapName, capacity, access, MemoryMappedFileOptions.DelayAllocatePages, null, HandleInheritability.None);
+                       return CreateOrOpen (mapName, capacity, access, MemoryMappedFileOptions.None, null, HandleInheritability.None);
                }
 
                [MonoLimitation ("Named mappings scope is process local")]
index 9362f00b1626a3e4aab06a5dc47f34d51358a6e0..b0be2e4f1885c20f28947b8de734b76d478a96d8 100644 (file)
@@ -92,7 +92,7 @@ namespace System.IO.MemoryMappedFiles
 
                public void Flush (IntPtr capacity)
                {
-                       MemoryMapImpl.Flush (m_viewHandle.DangerousGetHandle ());
+                       m_viewHandle.Flush ();
                }
                
                protected virtual void Dispose (bool disposing)
index 27191c37ed2b7b121d2f1926471d459add1d013f..9c273b84a596e848680054d9889147050a6b2530 100644 (file)
@@ -56,16 +56,28 @@ namespace MonoTests.System.IO.MemoryMappedFiles {
                        return "test-" + named_index++;
                }
 
-
+               static string baseTempDir = Path.Combine (Path.GetTempPath (), typeof (MemoryMappedFileTest).FullName);
                static string tempDir = Path.Combine (Path.GetTempPath (), typeof (MemoryMappedFileTest).FullName);
 
                string fname;
 
-               [SetUp]
-               protected void SetUp () {
-                       if (Directory.Exists (tempDir))
-                               Directory.Delete (tempDir, true);
+               [TestFixtureSetUp]
+               public void FixtureSetUp ()
+               {
+                       try {
+                               // Try to cleanup from any previous NUnit run.
+                               Directory.Delete (baseTempDir, true);
+                       } catch (Exception) {
+                       }
+               }
 
+               [SetUp]
+               public void SetUp ()
+               {
+                       int i = 0;
+                       do {
+                               tempDir = Path.Combine (baseTempDir, (++i).ToString());
+                       } while (Directory.Exists (tempDir));
                        Directory.CreateDirectory (tempDir);
 
                        fname = Path.Combine (tempDir, "basic.txt");
@@ -77,9 +89,14 @@ namespace MonoTests.System.IO.MemoryMappedFiles {
                }
 
                [TearDown]
-               protected void TearDown () {
-                       if (Directory.Exists (tempDir))
+               public void TearDown ()
+               {
+                       try {
+                               // This throws an exception under MS.NET and Mono on Windows,
+                               // since the directory contains open files.
                                Directory.Delete (tempDir, true);
+                       } catch (Exception) {
+                       }
                }
 
                [Test]
@@ -102,26 +119,16 @@ namespace MonoTests.System.IO.MemoryMappedFiles {
                public void CreateNew ()
                {
                        // This must succeed
-                       MemoryMappedFile.CreateNew (Path.Combine (tempDir, "createNew.test"), 8192);
-               }
-
-               [Test]
-               [ExpectedException (typeof (IOException))]
-               public void CreateNew_OnExistingFile ()
-               {
-                       // This must succeed
-                       MemoryMappedFile.CreateNew (Path.Combine (tempDir, "createNew.test"), 8192);
-                       
-                       // This should fail, the file exists
-                       MemoryMappedFile.CreateNew (Path.Combine (tempDir, "createNew.test"), 8192);
+                       MemoryMappedFile.CreateNew (MkNamedMapping (), 8192);
                }
 
                // Call this twice, it should always work
                [Test]
                public void CreateOrOpen_Multiple ()
                {
-                       MemoryMappedFile.CreateOrOpen (Path.Combine (tempDir, "createOrOpen.test"), 8192);
-                       MemoryMappedFile.CreateOrOpen (Path.Combine (tempDir, "createOrOpen.test"), 8192);
+                       var name = MkNamedMapping ();
+                       MemoryMappedFile.CreateOrOpen (name, 8192);
+                       MemoryMappedFile.CreateOrOpen (name, 8192);
                }
 
                [Test]
@@ -134,7 +141,7 @@ namespace MonoTests.System.IO.MemoryMappedFiles {
                        // We are requesting fewer bytes to map.
                        MemoryMappedFile.CreateFromFile (f, FileMode.Open, "myMap", 4192);
                }
-       
+
                [Test]
                public void CreateFromFile_Null () {
                        AssertThrows<ArgumentNullException> (delegate () {
@@ -252,6 +259,9 @@ namespace MonoTests.System.IO.MemoryMappedFiles {
                [Test]
                public void NamedMappingToInvalidFile ()
                {
+                       if (Environment.OSVersion.Platform != PlatformID.Unix) {
+                               Assert.Ignore ("Backslashes in mapping names are disallowed on .NET and Mono on Windows");
+                       }
                        var fileName = Path.Combine (tempDir, "temp_file_123");
                if (File.Exists (fileName))
                    File.Delete (fileName);
@@ -352,7 +362,7 @@ namespace MonoTests.System.IO.MemoryMappedFiles {
                }
 
                [Test]
-               [ExpectedException(typeof(IOException))]
+               [ExpectedException(typeof(UnauthorizedAccessException))]
                public void CreateViewStreamWithOffsetPastFileEnd ()
                {
                        string f = Path.Combine (tempDir, "8192-file");
@@ -365,7 +375,7 @@ namespace MonoTests.System.IO.MemoryMappedFiles {
                }
 
                [Test]
-               [ExpectedException(typeof(IOException))]
+               [ExpectedException(typeof(UnauthorizedAccessException))]
                public void CreateViewStreamWithOffsetPastFileEnd2 ()
                {
                        string f = Path.Combine (tempDir, "8192-file");
@@ -394,7 +404,7 @@ namespace MonoTests.System.IO.MemoryMappedFiles {
 
                        MemoryMappedViewStream stream = mappedFile.CreateViewStream (pageSize * 2, 0, MemoryMappedFileAccess.ReadWrite);
 #if !MONOTOUCH
-                       Assert.AreEqual (stream.Capacity, Environment.SystemPageSize);
+                       Assert.AreEqual (Environment.SystemPageSize, stream.Capacity);
 #endif
                        stream.Write (new byte [pageSize], 0, pageSize);
                }
@@ -407,9 +417,39 @@ namespace MonoTests.System.IO.MemoryMappedFiles {
                        File.WriteAllBytes (f, new byte [size]);
 
                        FileStream file = File.OpenRead (f);
-                       MemoryMappedFile.CreateFromFile (file, null, size, MemoryMappedFileAccess.ReadExecute, null, 0, false);
+                       MemoryMappedFile.CreateFromFile (file, null, size, MemoryMappedFileAccess.Read, null, 0, false);
                }
-       }
-}
 
+               [Test]
+               [ExpectedException(typeof(ArgumentOutOfRangeException))]
+               public void CreateNewLargerThanLogicalAddressSpace ()
+               {
+                       if (IntPtr.Size != 4) {
+                               Assert.Ignore ("Only applies to 32-bit systems");
+                       }
+                       MemoryMappedFile.CreateNew (MkNamedMapping (), (long) uint.MaxValue + 1);
+               }
 
+               [Test]
+               [ExpectedException(typeof(ArgumentOutOfRangeException))]
+               public void CreateOrOpenLargerThanLogicalAddressSpace ()
+               {
+                       if (IntPtr.Size != 4) {
+                               Assert.Ignore ("Only applies to 32-bit systems");
+                       }
+                       MemoryMappedFile.CreateOrOpen (MkNamedMapping (), (long) uint.MaxValue + 1);
+               }
+
+               [Test]
+               public void NamedMappingWithDelayAllocatePages ()
+               {
+                       var name = MkNamedMapping ();
+                       using (var m0 = MemoryMappedFile.CreateNew(name, 4096, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, HandleInheritability.None)) {
+                               using (MemoryMappedViewAccessor v0 = m0.CreateViewAccessor ()) {
+                                       Assert.AreEqual (0, v0.ReadInt32 (0));
+                               }
+                       }
+               }
+
+       }
+}
index a9389f9b49710d088c2f7baf64b566d424566a2c..ceef4c02157565a3e3ce4f4f0e0ef046e8ffd06f 100644 (file)
@@ -34,12 +34,9 @@ using System.Text;
 using System.Threading;
 using NUnit.Framework;
 using System.Linq;
-using NUnit.Framework.SyntaxHelpers;
 using NUnit.Framework.Constraints;
 using System.Diagnostics;
 
-namespace NUnit.Framework.SyntaxHelpers { class Dummy {} }
-
 namespace MonoTests.System.Linq
 {
        [TestFixture]
diff --git a/mcs/class/System.Data.Linq/build/.gitignore b/mcs/class/System.Data.Linq/build/.gitignore
new file mode 100644 (file)
index 0000000..f2cf7dc
--- /dev/null
@@ -0,0 +1,2 @@
+Northwind.db3
+
index 1079699a00fdf4e7c0e9fc00b93647933827697f..22f797c60f45de74c02e24453283aa7be8030900 100644 (file)
@@ -1,3 +1,4 @@
+../../test-helpers/NunitHelpers.cs
 ../examples/DbLinq.SQLite.Example/nwind/Northwind.cs
 ../src/DbLinq.Sqlite/Test/DirectDataContext.cs
 ../src/DbLinq.Sqlite/Test/TestBase_mono.cs
index bf28637588ce4107b9df01ff7077386fc17122d2..71e2154664a5940fe59b458727be871ecb24e5ab 100644 (file)
@@ -25,15 +25,14 @@ sqlite_tests_dep = \
 
 $(sqlite_tests): $(sqlite_tests_dep)
        $(TEST_COMPILE) -target:library -out:$@ \
-               -r:System.Data.dll -r:$(the_assembly) -r:Mono.Data.Sqlite $(test_nunit_ref) \
+               -r:$(topdir)/class/lib/$(PROFILE)/System.Data.dll -r:$(the_assembly) -r:$(topdir)/class/lib/$(PROFILE)/Mono.Data.Sqlite.dll -r:$(topdir)/class/lib/$(PROFILE)/System.Core.dll -r:$(topdir)/class/lib/$(PROFILE)/System.dll -r:$(topdir)/class/lib/$(PROFILE)/System.Xml.dll $(test_nunit_ref) \
                $(TEST_MCS_FLAGS) -d:MONO_STRICT -d:SQLITE \
                @$< $(TEST_SOURCES_WITH_SPACES)
 
 test-sqlite: $(sqlite_tests)
 
 RUN_TEST_COMMAND = \
-       MONO_REGISTRY_PATH="$(HOME)/.mono/registry" $(TEST_RUNTIME) $(RUNTIME_FLAGS) $(TEST_HARNESS) $(1) -noshadow $(TEST_HARNESS_FLAGS) $(LOCAL_TEST_HARNESS_FLAGS) $(TEST_HARNESS_EXCLUDES) $(TEST_HARNESS_OUTPUT) -xml=TestResult-$(1:.dll=)-$(PROFILE).xml -out:TestResult-$(1:.dll=)-$(PROFILE).out $(FIXTURE_ARG) $(TESTNAME_ARG) ; \
-       xsltproc $(topdir)/build/nunit-summary.xsl TestResult-$(1)-$(PROFILE).xml > TestResult-$(1:.dll=)-$(PROFILE).log
+       MONO_REGISTRY_PATH="$(HOME)/.mono/registry" $(TEST_RUNTIME) $(RUNTIME_FLAGS) $(TEST_HARNESS) $(1) $(TEST_HARNESS_FLAGS) $(LOCAL_TEST_HARNESS_FLAGS) $(TEST_HARNESS_EXCLUDES) $(TEST_HARNESS_OUTPUT) -labels -format:nunit2 -result=TestResult-$(1:.dll=)-$(PROFILE).xml $(FIXTURE_ARG) $(TESTNAME_ARG) ;
 
 run-test-sqlite:
        $(call RUN_TEST_COMMAND,$(sqlite_tests))
index c9bea8ea40c594e715c35af32ad3789c10603f76..f2b6d3ede66e1a19fd2a1812c53784df489fce70 100644 (file)
@@ -71,7 +71,7 @@ using MsNorthwind;
             \r
 \r
             Assert.IsNotNull(dbCommand.CommandText);\r
-            Assert.Greater(dbCommand.Parameters.Count, 0);\r
+            AssertHelper.Greater(dbCommand.Parameters.Count, 0);\r
         }\r
     }\r
 }\r
index 5ea0dbc7d761f83e6eac880c174482a1c55ce012..9bd6aac50f90e6faa0e01157d6969f38d354f2a9 100644 (file)
@@ -186,7 +186,7 @@ using nwind;
             Northwind db = CreateDB();\r
             Expression<Func<Customer, bool>> predicate = c => c.City == "Paris";\r
             int count = db.Customers.Count(predicate);\r
-            Assert.Greater(count, 0); // Some databases have more than 1 customer in Paris\r
+            AssertHelper.Greater(count, 0); // Some databases have more than 1 customer in Paris\r
         }\r
 \r
         /// <summary>\r
index 87bf3d8cdeee9b5e7347f7df43ca47a0d2ec07cc..b8a1c728d8eea9ff9dcbaf6a9787ab24d910c074 100644 (file)
@@ -68,7 +68,7 @@ using nwind;
         {\r
             Northwind db = CreateDB();\r
             int result = db.ExecuteCommand("SELECT count(*) FROM \"Products\"");\r
-            Assert.Greater(result, 0, "Expecting some rows in Products table, got:" + result);\r
+            AssertHelper.Greater(result, 0, "Expecting some rows in Products table, got:" + result);\r
         }\r
 \r
         /// <summary>\r
@@ -85,7 +85,7 @@ using nwind;
             Northwind db = CreateDB();\r
             int result = db.ExecuteCommand("SELECT count(*) FROM [Products] WHERE [ProductID]>{0}", 3);\r
             //long iResult = base.ExecuteScalar(sql);\r
-            Assert.Greater(result, 0, "Expecting some rows in Products table, got:" + result);\r
+            AssertHelper.Greater(result, 0, "Expecting some rows in Products table, got:" + result);\r
         }\r
 \r
     }\r
index ea375055d7eff42f3f25fbcd002a30e9d7d6f16d..fac3d615da592c19bc60a65c3790046525a07c6a 100644 (file)
@@ -67,7 +67,7 @@ using nwind;
             string beforecountry = character.Country;\r
             character.Country = "Burmuda";\r
 \r
-            Assert.Greater(db.GetChangeSet().Updates.Count, 0);\r
+            AssertHelper.Greater(db.GetChangeSet().Updates.Count, 0);\r
             db.SubmitChanges();\r
 \r
             var character2 = db.Customers.First(c=>c.CustomerID==character.CustomerID);\r
index e420e84f6bbbf621550f8192920040ce02954382..dd976666e05742c322045241a451dc14c98f2613 100644 (file)
@@ -159,7 +159,7 @@ using nwind;
 \r
             var q3 = q1.Union(q2);\r
 \r
-            Assert.Greater(q1.Count(), 0);\r
+            AssertHelper.Greater(q1.Count(), 0);\r
             Assert.IsTrue(q1.Count() + q2.Count() >= q3.Count());\r
 \r
         }\r
index 1f443c32ac66030d295c8a83b74bbbef11f0b92b..efde50c3dcce75b227dda8bd8c37988e1da97f34 100644 (file)
@@ -234,7 +234,7 @@ namespace nwind
             var q = from p in db.Products select p;\r
             List<Product> products = q.ToList();\r
             int productCount = products.Count;\r
-            Assert.Greater(productCount, 0, "Expected some products, got none");\r
+            AssertHelper.Greater(productCount, 0, "Expected some products, got none");\r
         }\r
 \r
 #if !DEBUG && SQLITE\r
@@ -443,7 +443,7 @@ namespace nwind
                     select p;\r
 \r
             int count = q.Count();\r
-            Assert.Less(count, db.Customers.Count());\r
+            AssertHelper.Less(count, db.Customers.Count());\r
         }\r
 \r
         [Test]\r
@@ -455,7 +455,7 @@ namespace nwind
                     select p;\r
 \r
             int count = q.Count();\r
-            Assert.Less(count, db.Customers.Count());\r
+            AssertHelper.Less(count, db.Customers.Count());\r
         }\r
 \r
         [Test]\r
@@ -496,7 +496,7 @@ namespace nwind
         }\r
 \r
         [Test]\r
-        [ExpectedException(ExceptionType=typeof(InvalidOperationException), ExpectedMessage="Data context options cannot be modified after results have been returned from a query.")]\r
+        [ExpectedException(typeof(InvalidOperationException), ExpectedMessage="Data context options cannot be modified after results have been returned from a query.")]\r
         public void C13_Changing_ObjectTrackingEnabled2False()\r
         {\r
             Northwind db = CreateDB();\r
@@ -507,7 +507,7 @@ namespace nwind
         }\r
 \r
         [Test]\r
-        [ExpectedException(ExceptionType = typeof(InvalidOperationException), ExpectedMessage = "Data context options cannot be modified after results have been returned from a query.")]\r
+        [ExpectedException(typeof(InvalidOperationException), ExpectedMessage = "Data context options cannot be modified after results have been returned from a query.")]\r
         public void C14_Changing_DeferredLoadingEnabled2False()\r
         {\r
             Northwind db = CreateDB();\r
@@ -518,7 +518,7 @@ namespace nwind
         }\r
 \r
         [Test]\r
-        [ExpectedException(ExceptionType = typeof(InvalidOperationException), ExpectedMessage = "Object tracking is not enabled for the current data context instance.")]\r
+        [ExpectedException(typeof(InvalidOperationException), ExpectedMessage = "Object tracking is not enabled for the current data context instance.")]\r
         public void C15_SubmitChanges_DeferredLoadingEnabled_False()\r
         {\r
             Northwind db = CreateDB();\r
@@ -572,7 +572,7 @@ namespace nwind
                         .Join(db.GetTable<EmployeeTerritory>(), t => t.TerritoryID, l => l.TerritoryID, (t, l) => l)\r
                         .Join(db.GetTable<Employee>().Where(e => e.EmployeeID > 0), l => l.EmployeeID, e => e.EmployeeID, (l, e) => e);\r
             var employeeCount = q.Count();\r
-            Assert.Greater(employeeCount, 0, "Expected any employees, got count=" + employeeCount);\r
+            AssertHelper.Greater(employeeCount, 0, "Expected any employees, got count=" + employeeCount);\r
         }\r
 \r
         /// <summary>\r
@@ -839,7 +839,7 @@ namespace nwind
 \r
             var q = from p in db.Products where p.ProductName == "Chai" select p.ProductID;\r
             var productID = q.First();\r
-            Assert.Greater(productID, 0, "Expected penID>0, got " + productID);\r
+            AssertHelper.Greater(productID, 0, "Expected penID>0, got " + productID);\r
         }\r
 \r
 \r
@@ -880,7 +880,7 @@ namespace nwind
 \r
             var q = from p in db.Products where p.ProductName == "Chai" select p.ProductID;\r
             var productID = q.Last();\r
-            Assert.Greater(productID, 0, "Expected penID>0, got " + productID);\r
+            AssertHelper.Greater(productID, 0, "Expected penID>0, got " + productID);\r
         }\r
 \r
 #if !DEBUG && (POSTGRES || (MSSQL && !L2SQL))\r
@@ -902,11 +902,11 @@ namespace nwind
                 {\r
                     //int compareNames = prevProductName.CompareTo(p.ProductName);\r
                     int compareNames = string.Compare(prevProductName, p.ProductName, stringComparisonType);\r
-                    Assert.Less(compareNames, 0, "When ordering by names, expected " + prevProductName + " to come after " + p.ProductName);\r
+                    AssertHelper.Less(compareNames, 0, "When ordering by names, expected " + prevProductName + " to come after " + p.ProductName);\r
                 }\r
                 prevProductName = p.ProductName;\r
             }\r
-            //Assert.Greater(productID,0,"Expected penID>0, got "+productID);\r
+            //AssertHelper.Greater(productID,0,"Expected penID>0, got "+productID);\r
         }\r
 \r
         [Test]\r
@@ -915,7 +915,7 @@ namespace nwind
             Northwind db = CreateDB();\r
             //var q = from p in db.Products where "Chai"==p.ProductName select p.Order;\r
             //List<Order> penOrders = q.ToList();\r
-            //Assert.Greater(penOrders.Count,0,"Expected some orders for product 'Chai'");\r
+            //AssertHelper.Greater(penOrders.Count,0,"Expected some orders for product 'Chai'");\r
 \r
             var q =\r
                 from o in db.Orders\r
@@ -929,7 +929,7 @@ namespace nwind
                 Assert.IsNotNull(co.c.City, "Expected non-null customer city");\r
                 Assert.IsNotNull(co.o, "Expected non-null order");\r
             }\r
-            Assert.Greater(list1.Count, 0, "Expected some orders for London customers");\r
+            AssertHelper.Greater(list1.Count, 0, "Expected some orders for London customers");\r
         }\r
 \r
         [Test]\r
@@ -947,7 +947,7 @@ namespace nwind
                 Assert.IsNotNull(co.c, "Expected non-null customer");\r
                 Assert.IsNotNull(co.o, "Expected non-null order");\r
             }\r
-            Assert.Greater(list1.Count, 0, "Expected some orders for London customers");\r
+            AssertHelper.Greater(list1.Count, 0, "Expected some orders for London customers");\r
         }\r
 \r
         [Test]\r
@@ -962,7 +962,7 @@ namespace nwind
                 where c.City == "London"\r
                 select new { c, o };\r
 \r
-            Assert.Greater(q.ToList().Count, 0, "Expected some orders for London customers");\r
+            AssertHelper.Greater(q.ToList().Count, 0, "Expected some orders for London customers");\r
         }\r
 \r
         [Test]\r
@@ -987,7 +987,7 @@ namespace nwind
 #else\r
             int expectedCount = 2; //Oracle, Mysql: 'Toilet Paper' and 'iPod'\r
 #endif\r
-            Assert.Greater(prods.Count, expectedCount, "Expected couple of products with letter 'p'");\r
+            AssertHelper.Greater(prods.Count, expectedCount, "Expected couple of products with letter 'p'");\r
         }\r
 \r
         [Test]\r
@@ -1002,11 +1002,11 @@ namespace nwind
             ).Take(5);\r
             //var q = db.Products.Where( p=>p.ProductName.Contains("p")).Take(5);\r
             List<Product> prods = q.ToList();\r
-            Assert.Greater(prods.Count, 2, "Expected couple of products with letter 'p'");\r
+            AssertHelper.Greater(prods.Count, 2, "Expected couple of products with letter 'p'");\r
 \r
             var prodID0 = prods[0].ProductID;\r
             var prodID1 = prods[1].ProductID;\r
-            Assert.Greater(prodID0, prodID1, "Sorting is broken");\r
+            AssertHelper.Greater(prodID0, prodID1, "Sorting is broken");\r
         }\r
 \r
         [Test]\r
index 8d8c325cbec773aba06c7b293d75553ace8c292b..fe7a675318132bfcbb66b452cc5e859e594b00b1 100644 (file)
@@ -136,7 +136,7 @@ using Id = System.Int32;
         {\r
             var q = from p in db.Products select p;\r
             int productCount = q.Count();\r
-            Assert.Greater(productCount, 0, "Expected non-zero product count");\r
+            AssertHelper.Greater(productCount, 0, "Expected non-zero product count");\r
         }\r
 \r
         [Test]\r
@@ -144,7 +144,7 @@ using Id = System.Int32;
         {\r
             var q = from p in db.Products select p.ProductID;\r
             int productCount = q.Count();\r
-            Assert.Greater(productCount, 0, "Expected non-zero product count");\r
+            AssertHelper.Greater(productCount, 0, "Expected non-zero product count");\r
             Console.WriteLine();\r
         }\r
         [Test]\r
@@ -152,7 +152,7 @@ using Id = System.Int32;
         {\r
             var q = from p in db.Products select p.ProductID;\r
             int productCount = q.Count(i => i < 3);\r
-            Assert.Greater(productCount, 0, "Expected non-zero product count");\r
+            AssertHelper.Greater(productCount, 0, "Expected non-zero product count");\r
             Assert.IsTrue(productCount < 4, "Expected product count < 3");\r
         }\r
 \r
@@ -161,7 +161,7 @@ using Id = System.Int32;
         {\r
             var q = from p in db.Products select p.ProductID;\r
             var maxID = q.Max();\r
-            Assert.Greater(maxID, 0, "Expected non-zero product count");\r
+            AssertHelper.Greater(maxID, 0, "Expected non-zero product count");\r
         }\r
 \r
         [Test]\r
@@ -169,7 +169,7 @@ using Id = System.Int32;
         {\r
             var q = from p in db.Products select p.ProductID;\r
             var minID = q.Min();\r
-            Assert.Greater(minID, 0, "Expected non-zero product count");\r
+            AssertHelper.Greater(minID, 0, "Expected non-zero product count");\r
         }\r
 \r
 #if !ORACLE // picrap: this test causes an internal buffer overflow when marshaling with oracle win32 driver\r
@@ -179,7 +179,7 @@ using Id = System.Int32;
         {\r
             var q = from p in db.Products select p.ProductID;\r
             double avg = q.Average();\r
-            Assert.Greater(avg, 0, "Expected non-zero productID average");\r
+            AssertHelper.Greater(avg, 0, "Expected non-zero productID average");\r
         }\r
 \r
 #endif\r
@@ -268,7 +268,7 @@ using Id = System.Int32;
             var q4 = from p in db.Products select p.ProductName + p.ProductID;\r
             //var q4 = from p in db.Products select p.ProductID;\r
             var q5 = q4.ToList();\r
-            Assert.Greater(q5.Count, 2, "Expected to see some concat strings");\r
+            AssertHelper.Greater(q5.Count, 2, "Expected to see some concat strings");\r
             foreach (string s0 in q5)\r
             {\r
                 bool startWithLetter = Char.IsLetter(s0[0]);\r
@@ -288,7 +288,7 @@ using Id = System.Int32;
                      select p.ProductName+p.ProductID;\r
             //var q4 = from p in db.Products select p.ProductID;\r
             //var q5 = q4.ToList();\r
-            Assert.Greater( q4.Count(), 2, "Expected to see some concat strings");\r
+            AssertHelper.Greater( q4.Count(), 2, "Expected to see some concat strings");\r
             foreach(string s0 in q4)\r
             {\r
                 bool startWithLetter = Char.IsLetter(s0[0]);\r
@@ -312,8 +312,8 @@ using Id = System.Int32;
                                           CustomerID = c.CustomerID\r
                                       });\r
             var list = q.ToList();\r
-            Assert.Greater(list.Count(), 0, "Expected list");\r
-            //Assert.Greater(list.Count(), 0, "Expected list");\r
+            AssertHelper.Greater(list.Count(), 0, "Expected list");\r
+            //AssertHelper.Greater(list.Count(), 0, "Expected list");\r
             Assert.Ignore("test passed but: theoretically constructions of entity types are not allowed");\r
         }\r
 \r
@@ -331,8 +331,8 @@ using Id = System.Int32;
             //this OrderBy clause messes up the SQL statement\r
             var q2 = q.OrderBy(c => c.CustomerID);\r
             var list = q2.ToList();\r
-            Assert.Greater(list.Count(), 0, "Expected list");\r
-            //Assert.Greater(list.Count(), 0, "Expected list");\r
+            AssertHelper.Greater(list.Count(), 0, "Expected list");\r
+            //AssertHelper.Greater(list.Count(), 0, "Expected list");\r
         }\r
 \r
 \r
@@ -344,7 +344,7 @@ using Id = System.Int32;
                     orderby c.ContactName ?? ""\r
                     select c;\r
             var list = q.ToList();\r
-            Assert.Greater(list.Count(), 0, "Expected list");\r
+            AssertHelper.Greater(list.Count(), 0, "Expected list");\r
         }\r
 \r
         [Test(Description = "Non-dynamic version of DL5_NestedObjectSelect")]\r
index 4d87952ed79e63e09cf587601e842cb2db2a6728..9ff4496ee8bbb3dd413af5a111b6ac3d835a8087 100644 (file)
@@ -231,10 +231,10 @@ using nwind;
                      select new { g.Key, OrderCount = g.Count() };\r
 \r
             var lst = q2.ToList();\r
-            Assert.Greater(lst.Count, 0, "Expected some grouped order results");\r
+            AssertHelper.Greater(lst.Count, 0, "Expected some grouped order results");\r
             var result0 = lst[0];\r
             Assert.IsTrue(result0.Key != null, "Key must be non-null");\r
-            Assert.Greater(result0.OrderCount, 0, "Count must be > 0");\r
+            AssertHelper.Greater(result0.OrderCount, 0, "Count must be > 0");\r
             //select new { g.Key , SumPerCustomer = g.Sum(o2=>o2.OrderID) };\r
         }\r
 \r
@@ -252,10 +252,10 @@ using nwind;
                      select new { g.Key, OrderCount = g.Count() };\r
 \r
             var lst = q2.ToList();\r
-            Assert.Greater(lst.Count, 0, "Expected some grouped order results");\r
+            AssertHelper.Greater(lst.Count, 0, "Expected some grouped order results");\r
             var result0 = lst[0];\r
             Assert.IsTrue(result0.Key != null, "Key must be non-null");\r
-            Assert.Greater(result0.OrderCount, 0, "Count must be > 0");\r
+            AssertHelper.Greater(result0.OrderCount, 0, "Count must be > 0");\r
             //select new { g.Key , SumPerCustomer = g.Sum(o2=>o2.OrderID) };\r
         }\r
 \r
@@ -272,12 +272,12 @@ using nwind;
                      //where g.Count()>1\r
                      select new { g.Key, OrderSum = g.Sum(o => o.OrderID) };\r
             var lst = q2.ToList();\r
-            Assert.Greater(lst.Count, 0, "Expected some grouped order results");\r
+            AssertHelper.Greater(lst.Count, 0, "Expected some grouped order results");\r
             foreach (var result in lst)\r
             {\r
                 Console.WriteLine("  Result: custID=" + result.Key + " sum=" + result.OrderSum);\r
                 Assert.IsTrue(result.Key != null, "Key must be non-null");\r
-                Assert.Greater(result.OrderSum, 0, "OrderSum must be > 0");\r
+                AssertHelper.Greater(result.OrderSum, 0, "OrderSum must be > 0");\r
             }\r
             //select new { g.Key , SumPerCustomer = g.Sum(o2=>o2.OrderID) };\r
         }\r
index 0c58ea44d4cbefd5efec0dffd7a9f2b588702477..48e0020e30fc8e9cb3334fc7167ff4e0619e0773 100644 (file)
@@ -331,7 +331,7 @@ using nwind;
             decimal[] d = new decimal[] { 1, 4, 5, 6, 10248, 10255 };\r
             var q = db.OrderDetails.Where(o => d.Contains(o.OrderID));\r
 \r
-            Assert.Greater(q.Count(), 0);\r
+            AssertHelper.Greater(q.Count(), 0);\r
         }\r
 \r
 \r
index 3d1981a405db66e0839c904a66b8ae41945fdf60..dabe2f12a7819a833252d38b3ec60a713d51995a 100644 (file)
@@ -265,7 +265,7 @@ using DbLinq.Data.Linq;
 \r
 \r
             var list = query.ToList();\r
-            Assert.Greater(list.Count, 0);\r
+            AssertHelper.Greater(list.Count, 0);\r
         }\r
 \r
 #if !DEBUG && SQLITE\r
@@ -299,7 +299,7 @@ using DbLinq.Data.Linq;
 \r
 \r
             var list = query.ToList();\r
-            Assert.Greater(list.Count, 0);\r
+            AssertHelper.Greater(list.Count, 0);\r
         }\r
 \r
 \r
@@ -334,7 +334,7 @@ using DbLinq.Data.Linq;
 \r
 \r
             var list = query.ToList();\r
-            Assert.Greater(list.Count, 0);\r
+            AssertHelper.Greater(list.Count, 0);\r
         }\r
 \r
 #if !DEBUG && (SQLITE || MSSQL)\r
@@ -354,7 +354,7 @@ using DbLinq.Data.Linq;
             \r
 \r
             var list = query.ToList();\r
-            Assert.Greater(list.Count, 0);\r
+            AssertHelper.Greater(list.Count, 0);\r
         }\r
 \r
 #if !DEBUG && SQLITE\r
@@ -388,7 +388,7 @@ using DbLinq.Data.Linq;
 \r
 \r
             var list = query.ToList();\r
-            Assert.Greater(list.Count, 0);\r
+            AssertHelper.Greater(list.Count, 0);\r
         }\r
 \r
 #if !DEBUG && SQLITE\r
@@ -410,7 +410,7 @@ using DbLinq.Data.Linq;
 \r
             var list = query.ToList();\r
 \r
-            Assert.Greater(list.Count, 0);\r
+            AssertHelper.Greater(list.Count, 0);\r
         }\r
 \r
 #if !DEBUG && POSTGRES\r
@@ -443,7 +443,7 @@ using DbLinq.Data.Linq;
 \r
                 var list = query.ToList();\r
 \r
-                Assert.Greater(list.Count, 0);\r
+                AssertHelper.Greater(list.Count, 0);\r
             }\r
             finally\r
             {\r
@@ -481,7 +481,7 @@ using DbLinq.Data.Linq;
 \r
                 var list = query.ToList();\r
 \r
-                Assert.Greater(list.Count, 0);\r
+                AssertHelper.Greater(list.Count, 0);\r
             }\r
             finally\r
             {\r
index 40503fed4f534d09174c598ac28f34299f5234b4..16a0b0a7ba0b478dd10b0d763fce6ab91634f70a 100644 (file)
@@ -53,7 +53,7 @@ using nwind;
         {\r
             var db = CreateDB();\r
             var customer = db.Customers.First();\r
-            Assert.Greater(customer.Orders.Count, 0);\r
+            AssertHelper.Greater(customer.Orders.Count, 0);\r
         }\r
 \r
 #if !DEBUG && (SQLITE || (MSSQL && !L2SQL))\r
@@ -65,7 +65,7 @@ using nwind;
             var db = CreateDB();\r
             var results = (from c in db.Customers select c.Orders).ToList();\r
 \r
-            Assert.Greater(results.Count, 0);\r
+            AssertHelper.Greater(results.Count, 0);\r
         }\r
 \r
         [Test]\r
@@ -98,7 +98,7 @@ using nwind;
             var db = CreateDB();\r
             var customer = db.Customers.First();\r
 \r
-            Assert.Greater(customer.Orders.Count, 0, "#1");\r
+            AssertHelper.Greater(customer.Orders.Count, 0, "#1");\r
             Assert.IsTrue(customer.Orders.HasLoadedOrAssignedValues, "#2");\r
             customer.Orders.SetSource(System.Linq.Enumerable.Empty<Order>());\r
         }\r
@@ -136,7 +136,7 @@ using nwind;
             int ordersCount = (from cust in db.Customers\r
                                select cust.Orders.Count).First();\r
 \r
-            Assert.Greater(ordersCount, 0);\r
+            AssertHelper.Greater(ordersCount, 0);\r
 \r
             var customer2 = db.Customers.First();\r
             customer2.Orders.SetSource(System.Linq.Enumerable.Empty<Order>());\r
@@ -154,11 +154,11 @@ using nwind;
             var c = db.Customers.First();\r
 \r
             int beforeCount = c.Orders.Count;\r
-            Assert.Greater(beforeCount, 0);\r
+            AssertHelper.Greater(beforeCount, 0);\r
             c.Orders.Clear();\r
             Assert.AreEqual(c.Orders.Count, 0);\r
             c.Orders.AddRange(db.Orders);\r
-            Assert.Greater(c.Orders.Count, beforeCount);\r
+            AssertHelper.Greater(c.Orders.Count, beforeCount);\r
             db.Refresh(RefreshMode.OverwriteCurrentValues, c.Orders);\r
 \r
             Assert.AreEqual(c.Orders.Count, beforeCount);\r
@@ -174,13 +174,13 @@ using nwind;
             var c = db.Customers.First();\r
 \r
             int beforeCount = c.Orders.Count;\r
-            Assert.Greater(beforeCount, 0);\r
+            AssertHelper.Greater(beforeCount, 0);\r
             c.Orders.Clear();\r
             Assert.AreEqual(c.Orders.Count, 0);\r
             c.Orders.AddRange(db.Orders);\r
 \r
             int middleCount = c.Orders.Count;\r
-            Assert.Greater(c.Orders.Count, beforeCount);\r
+            AssertHelper.Greater(c.Orders.Count, beforeCount);\r
 \r
             db.Refresh(RefreshMode.KeepCurrentValues, c.Orders);\r
             Assert.AreEqual(c.Orders.Count, middleCount);\r
@@ -233,7 +233,7 @@ using nwind;
         {\r
             var db = CreateDB();\r
             var customer = db.Customers.Where(c => c.Orders.Count > 0).First();\r
-            Assert.Greater(customer.Orders.Count, 0);\r
+            AssertHelper.Greater(customer.Orders.Count, 0);\r
             bool ok;\r
             System.ComponentModel.ListChangedEventArgs args = null;\r
             customer.Orders.ListChanged += delegate(object sender, System.ComponentModel.ListChangedEventArgs a) \r
index f792f8e585fb0e173c1d07d5553c36dfbc050535..e32291198abae2c9f7e5920020984dceb129f7a0 100644 (file)
@@ -86,10 +86,10 @@ using nwind;
             foreach (var c in q)\r
             {\r
                 Assert.IsNotNull(c.CustomerID);\r
-                Assert.Greater(c.OrderCount, -1);\r
+                AssertHelper.Greater(c.OrderCount, -1);\r
                 count++;\r
             }\r
-            Assert.Greater(count, 0);\r
+            AssertHelper.Greater(count, 0);\r
         }\r
 \r
         [Test]\r
@@ -103,10 +103,10 @@ using nwind;
             foreach (var v in q)\r
             {\r
                 Assert.IsNotNull(v.c.CustomerID);\r
-                Assert.Greater(v.OrderCount, -1);\r
+                AssertHelper.Greater(v.OrderCount, -1);\r
                 count++;\r
             }\r
-            Assert.Greater(count, 0);\r
+            AssertHelper.Greater(count, 0);\r
         }\r
 \r
         [Test]\r
@@ -121,7 +121,7 @@ using nwind;
                 Assert.IsTrue(c.CustomerID!=null, "Non-null customerID required");\r
                 count++;\r
             }\r
-            Assert.Greater(count, 0);\r
+            AssertHelper.Greater(count, 0);\r
         }\r
 #endif\r
     }\r
index 3aa1c9e1b6f1484b396c8124c6b95cc4e8c97d3d..08ed664f1b3c16cfeab659b9a61fe7cdd0ffc967 100644 (file)
@@ -161,7 +161,7 @@ using nwind;
             var customer = new Customer();\r
             db.Customers.Attach(customer, originalCustomer);\r
 \r
-            Assert.Greater(db.Customers.GetModifiedMembers(customer).Count(), 0);\r
+            AssertHelper.Greater(db.Customers.GetModifiedMembers(customer).Count(), 0);\r
         }\r
 \r
 #if !DEBUG && (SQLITE || POSTGRES || (MSSQL && !L2SQL))\r
index e593fc37c6e51b376f15d4f6086362102fd64966..ba0734df607a65de5db2347ea94a8a5abcac2fcb 100644 (file)
@@ -33,7 +33,7 @@ using NUnit.Framework;
 \r
 using nwind;\r
 \r
-#if MONO_STRICT && !MONO\r
+#if MONO_STRICT\r
 using System.Diagnostics;\r
 public static class Profiler\r
 {\r
index a30b2cff6a41dd2dac870107118fdb4dfee07e77..11fe0098a2a8b3e20d57fe91c44beb1da793ab69 100644 (file)
@@ -165,7 +165,7 @@ using Id = System.Int32;
             newProd.QuantityPerUnit = "33 1/2";\r
             db.Products.InsertOnSubmit(newProd);\r
             db.SubmitChanges();\r
-            Assert.Greater(newProd.ProductID, 0, "After insertion, ProductID should be non-zero");\r
+            AssertHelper.Greater(newProd.ProductID, 0, "After insertion, ProductID should be non-zero");\r
             //Assert.IsFalse(newProd.IsModified, "After insertion, Product.IsModified should be false");\r
             return (int)newProd.ProductID; //this test cab be used from delete tests\r
         }\r
@@ -180,7 +180,7 @@ using Id = System.Int32;
         public void G2_DeleteTest()\r
         {\r
             int insertedID = insertProduct_priv();\r
-            Assert.Greater(insertedID, 0, "DeleteTest cannot operate if row was not inserted");\r
+            AssertHelper.Greater(insertedID, 0, "DeleteTest cannot operate if row was not inserted");\r
 \r
             Northwind db = CreateDB();\r
 \r
@@ -200,7 +200,7 @@ using Id = System.Int32;
         public void G3_DeleteTest()\r
         {\r
             int insertedID = insertProduct_priv();\r
-            Assert.Greater(insertedID, 0, "DeleteTest cannot operate if row was not inserted");\r
+            AssertHelper.Greater(insertedID, 0, "DeleteTest cannot operate if row was not inserted");\r
 \r
             Northwind db = CreateDB();\r
 \r
index 431634ee37c844608af0fe6e97d360b27ff6f537..a3ef05590f275059b6e8f1a6bba5bc79a7d30f79 100644 (file)
@@ -1,10 +1,8 @@
 Some tests located require a connection to Oracle database to execute.
-To configure a connection, copy System.Data.OracleClient_test_default.dll.config.example
-to System.Data.OracleClient_test_default.dll.config and fill in the ConnectionString with appropriate Data Source.
+To configure a connection, set the MONO_TESTS_ORACLE_CONNECTION_STRING environment variable to a connection string like the following:
 
-If no System.Data.OracleClient_test_default.dll.config is present, those tests will be ignored.
+Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=<host ip>)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=<sid>)));uid=<user name>;pwd=<password>;
 
-To test .Net 2.0 profile, copy System.Data.OracleClient_test_default.dll.config
-to System.Data.OracleClient_test_net_2_0.dll.config and launch tests with PROFILE=net_2_0 .
+If the environment variable is not present, those tests will be ignored.
 
 Scripts for populating the database are located in Test/System.Data.OracleClient.jvm (for their usage, consult Test/System.Data.OracleClient.jvm/readme.txt).
diff --git a/mcs/class/System.Data.OracleClient/System.Data.OracleClient_test_default.dll.config.example b/mcs/class/System.Data.OracleClient/System.Data.OracleClient_test_default.dll.config.example
deleted file mode 100644 (file)
index 03703a7..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<configuration>
-       <appSettings>
-               <add key="ConnectionString" value="Data Source=;User ID=GHTDB;Password=GHTDB;" />
-       </appSettings>
-</configuration>
index 43e77ef1b220a4deaae4290a89729a76531ca3da..02c12ee3c947ee04bfb31a152a8935cbe4a60dd7 100644 (file)
@@ -51,7 +51,7 @@ namespace MonoTests.System.Data.OracleClient {
                 [TestFixtureSetUp]
                 public void FixtureSetUp ()
                 {
-                        connection_string = ConfigurationSettings.AppSettings.Get ("ConnectionString");
+                        connection_string = Environment.GetEnvironmentVariable ("MONO_TESTS_ORACLE_CONNECTION_STRING");
                         if(connection_string == null)
                                 Assert.Ignore ("Please consult README.tests.");
                 }
index a5feb72a00ba44d3ede3845b4f7b683384e90a99..70421c51a8dd6d1a7cc846e81d6261735282e75c 100755 (executable)
@@ -47,6 +47,7 @@ CREATE USER "GHTDB"
     TEMPORARY TABLESPACE "TEMP" ;
 
 GRANT CONNECT, RESOURCE, CREATE TABLE  TO "GHTDB";
+ALTER USER GHTDB quota unlimited on USERS;
 
 CREATE OR REPLACE  PACKAGE "GHTDB"."GHTPKG"  AS
        TYPE RCT1 IS REF CURSOR;
@@ -923,6 +924,7 @@ CREATE USER "GHTDB_EX"
     TEMPORARY TABLESPACE "TEMP" ;
 
 GRANT CONNECT, RESOURCE TO "GHTDB_EX";
+ALTER USER GHTDB_EX quota unlimited on USERS;
 
 CREATE OR REPLACE PACKAGE GHTDB_EX.GHTPKG
 AS
index 3fd8b632a9f0416ac6fb84124c0afd96e1ffb30f..ebe3de47ce51b12b707fbe72d145f116ce7b7c6e 100644 (file)
@@ -72,7 +72,7 @@ namespace MonoTests.System.Data.Utils {
 
                public static string ConnectionString {
                        get {
-                                string connection_string = Sys.Configuration.ConfigurationSettings.AppSettings["ConnectionString"];
+                                string connection_string = Environment.GetEnvironmentVariable ("MONO_TESTS_ORACLE_CONNECTION_STRING");
                                 if(connection_string == null)
                                         NUnit.Framework.Assert.Ignore ("Please consult README.tests.");
                                 return connection_string;
index 9c638e8252de6902084d8ce007233976202dc9cc..f544c35100675c0157f984d2ac1bea9a378339bd 100644 (file)
@@ -39,14 +39,7 @@ namespace MonoTests.System.Data.OracleClient
                [SetUp]
                public void SetUp()
                {
-                       try
-                       {
-                               _ConnectionString = MonoTests.System.Data.Utils.ConnectedDataProvider.ConnectionString;
-                       }
-                       catch(Exception ex)
-                       {
-                               EndCase(ex);
-                       }
+                       _ConnectionString = MonoTests.System.Data.Utils.ConnectedDataProvider.ConnectionString;
                }
 
                [TearDown]
index a9164fb27a7f7566484a53606e6e303833a2f451..9c36355d57f43f429d509dbe5cd36e21265c878e 100755 (executable)
@@ -1,15 +1,6 @@
 To run unit test the following should be prepared:
 
-1. Test\System.Data.OracleClient.J2EE.config should contain an ConnectionString setting, i.e.:
-
-<?xml version="1.0" encoding="utf-8" ?>
-<configuration>
-<appSettings>
-    <add key="ConnectionString" value="User ID=ghtdb;Password=ghtdb;Data Source=xp050" />
-  </appSettings>
-</configuration>
-
-2. A target db should be prepared with the relevant structure, following are the instruction for each supported database.
+A target db should be prepared with the relevant structure, following are the instruction for each supported database.
 
 in order to create the testing database, on ORACLE, run:
 Run the scripts with a user wich have administrator permissions. (by default user:system, password:mainsoft).
index 6b758dea47fae69022ab79245b4e2e6eeb3644f7..0dfd37e6402f0cfd2cb50d42dbe5413f641088b8 100644 (file)
@@ -48,7 +48,7 @@ namespace MonoTests.System.Data.OracleClient {
                 [TestFixtureSetUp]
                 public void FixtureSetUp ()
                 {
-                        connection_string = ConfigurationSettings.AppSettings.Get ("ConnectionString");
+                        connection_string = Environment.GetEnvironmentVariable ("MONO_TESTS_ORACLE_CONNECTION_STRING");
                         if(connection_string == null)
                                 Assert.Ignore ("Please consult README.tests.");
                 }
index d625b6bf129ac25230f1c2e35a9d80002b624b14..29c2e9022c74553dfb14d5ebab6aa3228eaffd12 100644 (file)
@@ -52,7 +52,7 @@ namespace MonoTests.System.Data.OracleClient
                [TestFixtureSetUp]
                public void FixtureSetUp ()
                {
-                       connection_string = ConfigurationSettings.AppSettings.Get ("ConnectionString");
+                       connection_string = Environment.GetEnvironmentVariable ("MONO_TESTS_ORACLE_CONNECTION_STRING");
                }
 
                [SetUp]
index e8a641299b351597bbcaaa4cfc549055fa665dbc..0806c36fb52977bfd5104e32117ff0e1e4d07994 100644 (file)
@@ -37,6 +37,8 @@ TXT_RESOURCE_STRINGS = ../referencesource/System.Data/system.data.txt
 TEST_LIB_REFS = System.Core Mono.Data.Sqlite
 TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) -nowarn:618,169,612,219,168
 
+TEST_NUNITLITE_APP_CONFIG_GLOBAL=Test/test-config-file
+
 TEST_MONO_PATH = .
 
 EXTRA_DISTFILES = \
@@ -45,7 +47,7 @@ EXTRA_DISTFILES = \
        $(wildcard Test/System.Xml/*.xml)               \
        $(wildcard Test/System.Xml/*.xsd)               \
        $(wildcard Test/System.Data/schemas/*.xsd)              \
-       app_test_net_4_x.config                 \
+       Test/test-config-file                   \
        Test/System.Data/binserialize/*.bin     \
        SqliteTest.db   \
        referencesource.sources
@@ -91,8 +93,3 @@ gen_SqlParameterCollection.cs: ../referencesource/System.Data/System/Data/Provid
        sed -e s/PARAMETEROBJECTNAME/SqlParameter/g >$@
 
 include ../../build/library.make
-
-$(test_lib): $(test_lib).config
-
-$(test_lib).config: app_test_$(PROFILE).config
-       cp $< $@
index f7248acb6bcc5dd554bf5b75c6c64609d52a1261..ff5dc821d854f550cd59f6b5ab6be1db6207fb17 100644 (file)
@@ -931,13 +931,21 @@ namespace System.Data.SqlClient
                                if (Client.Available <= 0)
                                        return -1; // Error
 
-                               IPEndPoint endpoint = CreateLocalEndpoint ();
-                               if (endpoint == null)
-                                       return -1;
+                               IPEndPoint remoteEndpoint;
+                               switch (Client.AddressFamily) {
+                                       case AddressFamily.InterNetwork:
+                                               remoteEndpoint = new IPEndPoint(IPAddress.Any, 0);
+                                               break;
+                                       case AddressFamily.InterNetworkV6:
+                                               remoteEndpoint = new IPEndPoint(IPAddress.IPv6Any, 0);
+                                               break;
+                                       default:
+                                               return -1; // Error
+                               }
 
                                Byte [] rawrs;
 
-                               rawrs = Receive (ref endpoint);
+                               rawrs = Receive (ref remoteEndpoint);
 
                                string rs = Encoding.ASCII.GetString (rawrs);
 
@@ -959,16 +967,6 @@ namespace System.Data.SqlClient
 
                                return SqlServerTcpPort;
                        }
-
-                       IPEndPoint CreateLocalEndpoint ()
-                       {
-                               foreach (var addr in Dns.GetHostEntry ("localhost").AddressList) {
-                                       if (addr.AddressFamily == Client.AddressFamily)
-                                               return new IPEndPoint (addr, 0);
-                               }
-
-                               return null;
-                       }
                }
 
                struct ColumnInfo
index 2fbdeb16c8ad740a5f0c178bec74bbcd05adc3e7..1357f253347fb5c49ff34958f600f70b6b374b9a 100644 (file)
@@ -34,9 +34,6 @@
 using NUnit.Framework;
 using System;
 using System.Data;
-#if !MOBILE
-using NUnit.Framework.SyntaxHelpers;
-#endif
 
 namespace MonoTests.System.Data
 {
index 2875dc0a1090f8bfa9dafb2ce0a061c0dcce8c15..37a12abcffdbe9947dd367e41a5d3e6b6483cde1 100644 (file)
@@ -34,9 +34,6 @@
 using NUnit.Framework;
 using System;
 using System.Data;
-#if !MOBILE
-using NUnit.Framework.SyntaxHelpers;
-#endif
 
 namespace MonoTests.System.Data
 {
index 7da3dca21f0b2db64186b45234732d8366561c5c..9ba7870e7e083ed90baebe989724d1a7c96515d0 100644 (file)
@@ -30,9 +30,6 @@
 using NUnit.Framework;
 using System;
 using System.Data;
-#if !MOBILE
-using NUnit.Framework.SyntaxHelpers;
-#endif
 
 namespace MonoTests.System.Data
 {
index 63d75f2c410a66a8f479cc1d57059168a7be79a3..f020a208e6f65e4e0c0eb416cf1aa587e7e4de4f 100644 (file)
@@ -34,9 +34,6 @@
 using NUnit.Framework;\r
 using System;\r
 using System.Data;\r
-#if !MOBILE\r
-using NUnit.Framework.SyntaxHelpers;\r
-#endif\r
 \r
 namespace MonoTests.System.Data\r
 {\r
index 945b22a484c133f221f36a64228b248096e57777..2e2890b4ec5b303c526d81cb0062289831fd1a55 100644 (file)
@@ -40,7 +40,7 @@ using Microsoft.CSharp;
 namespace MonoTests.System.Data
 {
        [TestFixture]
-       public class TypedDataSetGeneratorTest : Assertion
+       public class TypedDataSetGeneratorTest
        {
                private ICodeGenerator gen;
                private ICodeCompiler compiler;
@@ -70,20 +70,20 @@ namespace MonoTests.System.Data
                public void TestGenerateIdName ()
                {
                
-                       AssertEquals ("#1", "a", TypedDataSetGenerator.GenerateIdName ("a", gen));
-                       AssertEquals ("#2", "_int", TypedDataSetGenerator.GenerateIdName ("int", gen));
-                       AssertEquals ("#3", "_", TypedDataSetGenerator.GenerateIdName ("_", gen));
-                       AssertEquals ("#3-2", "_", TypedDataSetGenerator.GenerateIdName ("_", gen));
-                       AssertEquals ("#4", "_1", TypedDataSetGenerator.GenerateIdName ("1", gen));
-                       AssertEquals ("#4-2", "_1", TypedDataSetGenerator.GenerateIdName ("1", gen));
-                       AssertEquals ("#5", "_1a", TypedDataSetGenerator.GenerateIdName ("1a", gen));
-                       AssertEquals ("#6", "_1_2", TypedDataSetGenerator.GenerateIdName ("1*2", gen));
-                       AssertEquals ("#7", "__", TypedDataSetGenerator.GenerateIdName ("-", gen));
-                       AssertEquals ("#8", "__", TypedDataSetGenerator.GenerateIdName ("+", gen));
-                       AssertEquals ("#9", "_", TypedDataSetGenerator.GenerateIdName ("", gen));
-                       AssertEquals ("#10", "___", TypedDataSetGenerator.GenerateIdName ("--", gen));
-                       AssertEquals ("#11", "___", TypedDataSetGenerator.GenerateIdName ("++", gen));
-                       AssertEquals ("#12", "\u3042", TypedDataSetGenerator.GenerateIdName ("\u3042", gen));
+                       Assert.AreEqual ("a", TypedDataSetGenerator.GenerateIdName ("a", gen), "#1");
+                       Assert.AreEqual ("_int", TypedDataSetGenerator.GenerateIdName ("int", gen), "#2");
+                       Assert.AreEqual ("_", TypedDataSetGenerator.GenerateIdName ("_", gen), "#3");
+                       Assert.AreEqual ("_", TypedDataSetGenerator.GenerateIdName ("_", gen), "#3-2");
+                       Assert.AreEqual ("_1", TypedDataSetGenerator.GenerateIdName ("1", gen), "#4");
+                       Assert.AreEqual ("_1", TypedDataSetGenerator.GenerateIdName ("1", gen), "#4-2");
+                       Assert.AreEqual ("_1a", TypedDataSetGenerator.GenerateIdName ("1a", gen), "#5");
+                       Assert.AreEqual ("_1_2", TypedDataSetGenerator.GenerateIdName ("1*2", gen), "#6");
+                       Assert.AreEqual ("__", TypedDataSetGenerator.GenerateIdName ("-", gen), "#7");
+                       Assert.AreEqual ("__", TypedDataSetGenerator.GenerateIdName ("+", gen), "#8");
+                       Assert.AreEqual ("_", TypedDataSetGenerator.GenerateIdName ("", gen), "#9");
+                       Assert.AreEqual ("___", TypedDataSetGenerator.GenerateIdName ("--", gen), "#10");
+                       Assert.AreEqual ("___", TypedDataSetGenerator.GenerateIdName ("++", gen), "#11");
+                       Assert.AreEqual ("\u3042", TypedDataSetGenerator.GenerateIdName ("\u3042", gen), "#12");
                }
 
                [Test]
@@ -98,7 +98,7 @@ namespace MonoTests.System.Data
                        ccu.Namespaces.Add (cns);
                        CompilerResults r = compiler.CompileAssemblyFromDom (
                                new CompilerParameters (), ccu);
-                       AssertEquals (0, r.Errors.Count);
+                       Assert.AreEqual (0, r.Errors.Count);
                }
        }
 }
index 2be7b264d09d432d6411966d0ded3330209fe21c..b1f4d2d1b7c6815e0cc5d0ffb3f2c2da69361597 100644 (file)
@@ -33,9 +33,6 @@
 using NUnit.Framework;
 using System;
 using System.Data;
-#if !MOBILE
-using NUnit.Framework.SyntaxHelpers;
-#endif
 
 namespace MonoTests.System.Data
 {
diff --git a/mcs/class/System.Data/Test/test-config-file b/mcs/class/System.Data/Test/test-config-file
new file mode 100644 (file)
index 0000000..8135637
--- /dev/null
@@ -0,0 +1,45 @@
+       <configSections>
+               <section name="system.data_test" 
+                       type="System.Data.Common.DbProviderFactoriesConfigurationHandler, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
+               <section name="connectionStrings_test"
+                       type="System.Configuration.ConnectionStringsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
+       </configSections>
+       <system.data>
+               <DbProviderFactories>
+                       <add name="ProviderTest2.Name"
+                               invariant="ProviderTest2.InvariantName"
+                               support="FF"
+                               description="ProviderTest2.Description"
+                               type="ProviderTest2.AssemblyQualifiedName"/>
+               </DbProviderFactories>
+       </system.data>
+       <system.data_test>
+               <DbProviderFactories>
+                       <add name="ProviderTest3.Name"
+                               invariant="ProviderTest3.InvariantName"
+                               support="FF"
+                               description="ProviderTest3.Description"
+                               type="ProviderTest3.AssemblyQualifiedName"/>
+                       <clear />
+                       <add name="ProviderTest4.Name"
+                               invariant="ProviderTest4.InvariantName"
+                               support="FF"
+                               description="ProviderTest4.Description"
+                               type="ProviderTest4.AssemblyQualifiedName"/>
+                       <add name="ProviderTest5.Name"
+                               invariant="ProviderTest5.InvariantName"
+                               support="FF"
+                               description="ProviderTest5.Description"
+                               type="ProviderTest5.AssemblyQualifiedName"/>
+                       <remove invariant="ProviderTest5.InvariantName" />
+                       <add name="ProviderTest.Name"
+                               invariant="ProviderTest.InvariantName"
+                               support="FF"
+                               description="ProviderTest.Description"
+                               type="ProviderTest.AssemblyQualifiedName"/>
+               </DbProviderFactories>
+       </system.data_test>
+       <connectionStrings_test>
+               <add name="Publications" providerName="System.Data.SqlClient" 
+                       connectionString="Data Source=MyServer;Initial Catalog=pubs;integrated security=SSPI" />
+       </connectionStrings_test>
diff --git a/mcs/class/System.Data/app_test_mobile_static.config b/mcs/class/System.Data/app_test_mobile_static.config
deleted file mode 100644 (file)
index 4f31597..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<configuration>
-       <configSections>
-               <section name="system.data_test" 
-                       type="System.Data.Common.DbProviderFactoriesConfigurationHandler, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
-               <section name="connectionStrings_test"
-                       type="System.Configuration.ConnectionStringsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
-       </configSections>
-       <system.data>
-               <DbProviderFactories>
-                       <add name="ProviderTest2.Name"
-                               invariant="ProviderTest2.InvariantName"
-                               support="FF"
-                               description="ProviderTest2.Description"
-                               type="ProviderTest2.AssemblyQualifiedName"/>
-               </DbProviderFactories>
-       </system.data>
-       <system.data_test>
-               <DbProviderFactories>
-                       <add name="ProviderTest3.Name"
-                               invariant="ProviderTest3.InvariantName"
-                               support="FF"
-                               description="ProviderTest3.Description"
-                               type="ProviderTest3.AssemblyQualifiedName"/>
-                       <clear />
-                       <add name="ProviderTest4.Name"
-                               invariant="ProviderTest4.InvariantName"
-                               support="FF"
-                               description="ProviderTest4.Description"
-                               type="ProviderTest4.AssemblyQualifiedName"/>
-                       <add name="ProviderTest5.Name"
-                               invariant="ProviderTest5.InvariantName"
-                               support="FF"
-                               description="ProviderTest5.Description"
-                               type="ProviderTest5.AssemblyQualifiedName"/>
-                       <remove invariant="ProviderTest5.InvariantName" />
-                       <add name="ProviderTest.Name"
-                               invariant="ProviderTest.InvariantName"
-                               support="FF"
-                               description="ProviderTest.Description"
-                               type="ProviderTest.AssemblyQualifiedName"/>
-               </DbProviderFactories>
-       </system.data_test>
-       <connectionStrings_test>
-               <add name="Publications" providerName="System.Data.SqlClient" 
-                       connectionString="Data Source=MyServer;Initial Catalog=pubs;integrated security=SSPI" />
-       </connectionStrings_test>
-</configuration>
diff --git a/mcs/class/System.Data/app_test_net_4_x.config b/mcs/class/System.Data/app_test_net_4_x.config
deleted file mode 100644 (file)
index 4f31597..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<configuration>
-       <configSections>
-               <section name="system.data_test" 
-                       type="System.Data.Common.DbProviderFactoriesConfigurationHandler, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
-               <section name="connectionStrings_test"
-                       type="System.Configuration.ConnectionStringsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
-       </configSections>
-       <system.data>
-               <DbProviderFactories>
-                       <add name="ProviderTest2.Name"
-                               invariant="ProviderTest2.InvariantName"
-                               support="FF"
-                               description="ProviderTest2.Description"
-                               type="ProviderTest2.AssemblyQualifiedName"/>
-               </DbProviderFactories>
-       </system.data>
-       <system.data_test>
-               <DbProviderFactories>
-                       <add name="ProviderTest3.Name"
-                               invariant="ProviderTest3.InvariantName"
-                               support="FF"
-                               description="ProviderTest3.Description"
-                               type="ProviderTest3.AssemblyQualifiedName"/>
-                       <clear />
-                       <add name="ProviderTest4.Name"
-                               invariant="ProviderTest4.InvariantName"
-                               support="FF"
-                               description="ProviderTest4.Description"
-                               type="ProviderTest4.AssemblyQualifiedName"/>
-                       <add name="ProviderTest5.Name"
-                               invariant="ProviderTest5.InvariantName"
-                               support="FF"
-                               description="ProviderTest5.Description"
-                               type="ProviderTest5.AssemblyQualifiedName"/>
-                       <remove invariant="ProviderTest5.InvariantName" />
-                       <add name="ProviderTest.Name"
-                               invariant="ProviderTest.InvariantName"
-                               support="FF"
-                               description="ProviderTest.Description"
-                               type="ProviderTest.AssemblyQualifiedName"/>
-               </DbProviderFactories>
-       </system.data_test>
-       <connectionStrings_test>
-               <add name="Publications" providerName="System.Data.SqlClient" 
-                       connectionString="Data Source=MyServer;Initial Catalog=pubs;integrated security=SSPI" />
-       </connectionStrings_test>
-</configuration>
index 83e8ca47378f06ef7acdd6c3eb3dfa366abf4e94..4b7cf62280f8cf5ee961798a8d2ddc8f541ff3a8 100644 (file)
@@ -1,3 +1,4 @@
+../../test-helpers/NunitHelpers.cs
 ../../../build/common/Locale.cs
 ../System.Drawing/gdipEnums.cs    
 ../System.Drawing/gdipFunctions.cs
index 9848565605712e7fde336a7da9279d79c3dca56e..061d5e3ed70610688872b141a512f2e2fdeb3944 100644 (file)
@@ -38,9 +38,6 @@ using System.Drawing.Text;
 using System.Drawing.Imaging;\r
 using DrawingTestHelper;\r
 using System.IO;\r
-#if !MONOTOUCH\r
-using  NUnit.Framework.SyntaxHelpers;\r
-#endif\r
 \r
 namespace Test.Sys.Drawing.GraphicsFixtures {\r
        #region GraphicsFixtureProps\r
index 883ea72ebe25f4b079ae0a684e021cede538bda7..599edd8a8039f54801a5191592799319ee077632 100644 (file)
@@ -115,7 +115,8 @@ namespace System.Runtime.Remoting.Channels.Ipc.Win32
 
         public void StartListening(object data)
         {
-            serverChannel.StartListening(data);
+            if (serverChannel != null)
+                serverChannel.StartListening(data);
         }
 
         public object ChannelData
@@ -128,7 +129,8 @@ namespace System.Runtime.Remoting.Channels.Ipc.Win32
 
         public void StopListening(object data)
         {
-            serverChannel.StopListening(data);
+            if (serverChannel != null)
+                serverChannel.StopListening(data);
         }
 
         public string[] GetUrlsForUri(string objectURI)
index ff09e03824c327e865236b5a4b8568bdfb3bd3a6..8aae7d9e602904bd3c5b2c4e181e210051db3ffb 100644 (file)
@@ -1,3 +1,4 @@
+../../test-helpers/NunitHelpers.cs
 System.Runtime.Remoting.Channels.Tcp/TcpChannelTest.cs
 ServerObject.cs
 ContextsTest.cs
index 68930b0d640addd065d2408c87f3790d3fe5d006..c809f96c9401173bd5de5f7a6817026bd9291f24 100644 (file)
@@ -169,16 +169,12 @@ namespace MonoTests.Remoting.Http
                public void Main ()
                {
                        channel = new HttpChannel (0);
-                       try {
                        ChannelServices.RegisterChannel (channel);
                        MarshalByRefObject obj = (MarshalByRefObject) RemotingServices.Connect (
                                typeof (IFactorial),
                                "http://localhost:60000/MyEndPoint");
                        IFactorial cal = (IFactorial) obj;
-                       Assert.AreEqual (cal.CalculateFactorial (4), 24); 
-                       } finally {
-                       ChannelServices.UnregisterChannel (channel);
-                       }
+                       Assert.AreEqual (cal.CalculateFactorial (4), 24);
                }
                
                [TestFixtureSetUp]
index 831c69e72b54f79b0b9b454ec152261ea9864cc1..45f76791b7cf6841752a917937f876b03e70b52e 100644 (file)
@@ -78,7 +78,7 @@ namespace MonoTests.Remoting
                        IpcServerChannel chan = new IpcServerChannel (channelName, portName);
                        string[] uris = chan.GetUrlsForUri ("server.rem");
                        Assert.IsNotNull (uris);
-                       Assert.Greater (uris.Length, 0);
+                       AssertHelper.Greater (uris.Length, 0);
 
                        bool found = false;
                        foreach (string s in uris) {
@@ -101,7 +101,7 @@ namespace MonoTests.Remoting
                        IpcChannel chan = new IpcChannel (props, null, null);
                        string[] uris = chan.GetUrlsForUri ("server.rem");
                        Assert.IsNotNull (uris);
-                       Assert.Greater (uris.Length, 0);
+                       AssertHelper.Greater (uris.Length, 0);
 
                        bool found = false;
                        foreach (string s in uris) {
index f9ad75cd3ac4a05f55b984212b19982d795a576a..02c6a532c00ce24d94a757b312892a2df1920c86 100644 (file)
@@ -193,7 +193,7 @@ namespace MonoTests.Remoting
 \r
        // The main test class\r
        [TestFixture]\r
-       public class RemotingServicesTest : Assertion\r
+       public class RemotingServicesTest\r
        {\r
                private static int MarshalObjectId = 0;\r
 \r
@@ -233,13 +233,13 @@ namespace MonoTests.Remoting
                        MarshalObject objMarshal = NewMarshalObject ();\r
                        ObjRef objRef = RemotingServices.Marshal (objMarshal);\r
 \r
-                       Assert ("#A01", objRef.URI != null);\r
+                       Assert.IsNotNull (objRef.URI, "#A01");\r
 \r
                        MarshalObject objRem = (MarshalObject) RemotingServices.Unmarshal (objRef);\r
-                       AssertEquals ("#A02", objMarshal.Id, objRem.Id);\r
+                       Assert.AreEqual (objMarshal.Id, objRem.Id, "#A02");\r
 \r
                        objRem.Id = 2;\r
-                       AssertEquals ("#A03", objMarshal.Id, objRem.Id);\r
+                       Assert.AreEqual (objMarshal.Id, objRem.Id, "#A03");\r
 \r
                        // TODO: uncomment when RemotingServices.Disconnect is implemented\r
                        //RemotingServices.Disconnect(objMarshal);\r
@@ -248,7 +248,7 @@ namespace MonoTests.Remoting
 \r
                        objRef = RemotingServices.Marshal (objMarshal, objMarshal.Uri);\r
 \r
-                       Assert ("#A04", objRef.URI.EndsWith (objMarshal.Uri));\r
+                       Assert.IsTrue (objRef.URI.EndsWith (objMarshal.Uri), "#A04");\r
                        // TODO: uncomment when RemotingServices.Disconnect is implemented\r
                        //RemotingServices.Disconnect(objMarshal);\r
                }\r
@@ -261,7 +261,7 @@ namespace MonoTests.Remoting
                        ObjRef objRef = RemotingServices.Marshal (derivedObjMarshal, derivedObjMarshal.Uri, typeof (MarshalObject));\r
 \r
                        // Check that the type of the marshaled object is MarshalObject\r
-                       Assert ("#A05", objRef.TypeInfo.TypeName.StartsWith ((typeof (MarshalObject)).ToString ()));\r
+                       Assert.IsTrue (objRef.TypeInfo.TypeName.StartsWith ((typeof (MarshalObject)).ToString ()), "#A05");\r
 \r
                        // TODO: uncomment when RemotingServices.Disconnect is implemented\r
                        //RemotingServices.Disconnect(derivedObjMarshal);\r
@@ -273,11 +273,11 @@ namespace MonoTests.Remoting
                {\r
                        MarshalObject objMarshal = NewMarshalObject ();\r
 \r
-                       Assert ("#A06", RemotingServices.GetObjectUri (objMarshal) == null);\r
+                       Assert.IsNull (RemotingServices.GetObjectUri (objMarshal), "#A06");\r
 \r
                        RemotingServices.Marshal (objMarshal);\r
 \r
-                       Assert ("#A07", RemotingServices.GetObjectUri (objMarshal) != null);\r
+                       Assert.IsNotNull (RemotingServices.GetObjectUri (objMarshal), "#A07");\r
                        // TODO: uncomment when RemotingServices.Disconnect is implemented\r
                        //RemotingServices.Disconnect(objMarshal);\r
                }\r
@@ -297,7 +297,7 @@ namespace MonoTests.Remoting
                        try {\r
                                RemotingServices.Marshal (objMarshal, objMarshal.Uri);\r
                                MarshalObject objRem = (MarshalObject) RemotingServices.Connect (typeof (MarshalObject), "tcp://localhost:1236/" + objMarshal.Uri);\r
-                               Assert ("#A08", RemotingServices.IsTransparentProxy (objRem));\r
+                               Assert.IsTrue (RemotingServices.IsTransparentProxy (objRem), "#A08");\r
                        } finally {\r
                                ChannelServices.UnregisterChannel (chn);\r
                                RemotingServices.Disconnect (objMarshal);\r
@@ -324,7 +324,7 @@ namespace MonoTests.Remoting
                                // a real object\r
                                try {\r
                                        RemotingServices.Marshal (objRem, objMarshal.Uri);\r
-                                       Fail ("#1");\r
+                                       Assert.Fail ("#1");\r
                                } catch (RemotingException e) {\r
                                }\r
                        } finally {\r
@@ -355,15 +355,15 @@ namespace MonoTests.Remoting
                                objRem.Method1 ();\r
 \r
                                // Tests RemotingServices.GetMethodBaseFromMethodMessage()\r
-                               AssertEquals ("#A09", "Method1", proxy.MthBase.Name);\r
-                               Assert ("#A09.1", !proxy.IsMethodOverloaded);\r
+                               Assert.AreEqual ("Method1", proxy.MthBase.Name, "#A09");\r
+                               Assert.IsFalse (proxy.IsMethodOverloaded, "#A09.1");\r
 \r
                                objRem.Method2 ();\r
-                               Assert ("#A09.2", proxy.IsMethodOverloaded);\r
+                               Assert.IsTrue (proxy.IsMethodOverloaded, "#A09.2");\r
 \r
                                // Tests RemotingServices.ExecuteMessage();\r
                                // If ExecuteMessage does it job well, Method1 should be called 2 times\r
-                               AssertEquals ("#A10", 2, MarshalObject.Called);\r
+                               Assert.AreEqual (2, MarshalObject.Called, "#A10");\r
                        } finally {\r
                                ChannelServices.UnregisterChannel (chn);\r
                        }\r
@@ -380,14 +380,14 @@ namespace MonoTests.Remoting
 \r
                                MarshalObject objRem = (MarshalObject) Activator.GetObject (typeof (MarshalObject), "tcp://localhost:1238/MarshalObject.rem");\r
 \r
-                               Assert ("#A10.1", RemotingServices.IsTransparentProxy (objRem));\r
+                               Assert.IsTrue (RemotingServices.IsTransparentProxy (objRem), "#A10.1");\r
 \r
                                objRem.Method1 ();\r
                                Thread.Sleep (20);\r
-                               Assert ("#A10.2", !MarshalObject.IsMethodOneWay);\r
+                               Assert.IsFalse (MarshalObject.IsMethodOneWay, "#A10.2");\r
                                objRem.Method3 ();\r
                                Thread.Sleep (20);\r
-                               Assert ("#A10.3", MarshalObject.IsMethodOneWay);\r
+                               Assert.IsTrue (MarshalObject.IsMethodOneWay, "#A10.3");\r
                        } finally {\r
                                ChannelServices.UnregisterChannel (chn);\r
                        }\r
@@ -409,7 +409,7 @@ namespace MonoTests.Remoting
 \r
                                ObjRef objRefRem = RemotingServices.GetObjRefForProxy ((MarshalByRefObject) objRem);\r
 \r
-                               Assert ("#A11", objRefRem != null);\r
+                               Assert.IsNotNull (objRefRem, "#A11");\r
                        } finally {\r
                                ChannelServices.UnregisterChannel (chn);\r
                        }\r
@@ -429,8 +429,8 @@ namespace MonoTests.Remoting
 \r
                                RealProxy rp = RemotingServices.GetRealProxy (objRem);\r
 \r
-                               Assert ("#A12", rp != null);\r
-                               AssertEquals ("#A13", "MonoTests.System.Runtime.Remoting.RemotingServicesInternal.MyProxy", rp.GetType ().ToString ());\r
+                               Assert.IsNotNull (rp, "#A12");\r
+                               Assert.AreEqual ("MonoTests.System.Runtime.Remoting.RemotingServicesInternal.MyProxy", rp.GetType ().ToString (), "#A13");\r
                        } finally {\r
                                ChannelServices.UnregisterChannel (chn);\r
                        }\r
@@ -448,7 +448,7 @@ namespace MonoTests.Remoting
                                RemotingServices.Marshal (objRem);\r
 \r
                                objRem = (MarshalObject) Activator.GetObject (typeof (MarshalObject), "tcp://localhost:1242/" + objRem.Uri);\r
-                               Assert ("#A14", objRem != null);\r
+                               Assert.IsNotNull (objRem, "#A14");\r
                        } finally {\r
                                ChannelServices.UnregisterChannel (chn);\r
                        }\r
@@ -468,7 +468,7 @@ namespace MonoTests.Remoting
                                RemotingServices.Marshal (objRem);\r
 \r
                                Type typeRem = RemotingServices.GetServerTypeForUri (RemotingServices.GetObjectUri (objRem));\r
-                               AssertEquals ("#A15", type, typeRem);\r
+                               Assert.AreEqual (type, typeRem, "#A15");\r
                        } finally {\r
                                ChannelServices.UnregisterChannel (chn);\r
                        }\r
@@ -487,12 +487,12 @@ namespace MonoTests.Remoting
 \r
                                MarshalObject objRem = (MarshalObject) Activator.GetObject (typeof (MarshalObject), "tcp://localhost:1245/MarshalObject2.rem");\r
 \r
-                               Assert ("#A16", RemotingServices.IsObjectOutOfAppDomain (objRem));\r
-                               Assert ("#A17", RemotingServices.IsObjectOutOfContext (objRem));\r
+                               Assert.IsTrue (RemotingServices.IsObjectOutOfAppDomain (objRem), "#A16");\r
+                               Assert.IsTrue (RemotingServices.IsObjectOutOfContext (objRem), "#A17");\r
 \r
                                MarshalObject objMarshal = new MarshalObject ();\r
-                               Assert ("#A18", !RemotingServices.IsObjectOutOfAppDomain (objMarshal));\r
-                               Assert ("#A19", !RemotingServices.IsObjectOutOfContext (objMarshal));\r
+                               Assert.IsFalse (RemotingServices.IsObjectOutOfAppDomain (objMarshal), "#A18");\r
+                               Assert.IsFalse (RemotingServices.IsObjectOutOfContext (objMarshal), "#A19");\r
                        } finally {\r
                                ChannelServices.UnregisterChannel (chn);\r
                        }\r
@@ -510,16 +510,16 @@ namespace MonoTests.Remoting
                                MarshalObject objRem = (MarshalObject) Activator.GetObject (typeof (MarshalObject), "tcp://localhost:1246/app/obj3.rem");\r
                                MarshalObject objRem2 = (MarshalObject) Activator.GetObject (typeof (MarshalObject), "tcp://localhost:1246/obj3.rem");\r
 \r
-                               Assert ("#AN1", RemotingServices.IsTransparentProxy (objRem));\r
-                               Assert ("#AN2", RemotingServices.IsTransparentProxy (objRem2));\r
+                               Assert.IsTrue (RemotingServices.IsTransparentProxy (objRem), "#AN1");\r
+                               Assert.IsTrue (RemotingServices.IsTransparentProxy (objRem2), "#AN2");\r
 \r
-                               AssertNotNull ("#AN3", RemotingServices.GetServerTypeForUri ("obj3.rem"));\r
-                               AssertNotNull ("#AN4", RemotingServices.GetServerTypeForUri ("/app/obj3.rem"));\r
-                               AssertNull ("#AN5", RemotingServices.GetServerTypeForUri ("//app/obj3.rem"));\r
-                               AssertNull ("#AN6", RemotingServices.GetServerTypeForUri ("app/obj3.rem"));\r
-                               AssertNull ("#AN7", RemotingServices.GetServerTypeForUri ("/whatever/obj3.rem"));\r
-                               AssertNotNull ("#AN8", RemotingServices.GetServerTypeForUri ("/obj3.rem"));\r
-                               AssertNull ("#AN9", RemotingServices.GetServerTypeForUri ("//obj3.rem"));\r
+                               Assert.IsNotNull (RemotingServices.GetServerTypeForUri ("obj3.rem"), "#AN3");\r
+                               Assert.IsNotNull (RemotingServices.GetServerTypeForUri ("/app/obj3.rem"), "#AN4");\r
+                               Assert.IsNull (RemotingServices.GetServerTypeForUri ("//app/obj3.rem"), "#AN5");\r
+                               Assert.IsNull (RemotingServices.GetServerTypeForUri ("app/obj3.rem"), "#AN6");\r
+                               Assert.IsNull (RemotingServices.GetServerTypeForUri ("/whatever/obj3.rem"), "#AN7");\r
+                               Assert.IsNotNull (RemotingServices.GetServerTypeForUri ("/obj3.rem"), "#AN8");\r
+                               Assert.IsNull (RemotingServices.GetServerTypeForUri ("//obj3.rem"), "#AN9");\r
                        } finally {\r
                                ChannelServices.UnregisterChannel (chn);\r
                        }\r
@@ -534,7 +534,7 @@ namespace MonoTests.Remoting
                                RemotingConfiguration.RegisterWellKnownServiceType (typeof (MarshalObject), "getobjectwithchanneldata.rem", WellKnownObjectMode.Singleton);\r
 \r
                                string channelData = "test";\r
-                               AssertNotNull ("#01", Activator.GetObject (typeof (MarshalObject), "tcp://localhost:1247/getobjectwithchanneldata.rem", channelData));\r
+                               Assert.IsNotNull (Activator.GetObject (typeof (MarshalObject), "tcp://localhost:1247/getobjectwithchanneldata.rem", channelData), "#01");\r
                        } finally {\r
                                ChannelServices.UnregisterChannel (chn);\r
                        }\r
@@ -548,28 +548,28 @@ namespace MonoTests.Remoting
                        RemotingConfiguration.Configure (null);\r
 \r
                        o = RemotingServices.Connect (typeof (MarshalByRefObject), "tcp://localhost:3434/ff1.rem");\r
-                       Assert ("#m1", o is DD);\r
-                       Assert ("#m2", o is A);\r
-                       Assert ("#m3", o is B);\r
-                       Assert ("#m4", !(o is CC));\r
+                       Assert.IsInstanceOfType (typeof (DD), o, "#m1");\r
+                       Assert.IsInstanceOfType (typeof (A), o, "#m2");\r
+                       Assert.IsInstanceOfType (typeof (B), o, "#m3");\r
+                       AssertHelper.IsNotInstanceOfType (typeof (CC), !(o is CC), "#m4");\r
 \r
                        o = RemotingServices.Connect (typeof (A), "tcp://localhost:3434/ff3.rem");\r
-                       Assert ("#a1", o is DD);\r
-                       Assert ("#a2", o is A);\r
-                       Assert ("#a3", o is B);\r
-                       Assert ("#a4", !(o is CC));\r
+                       Assert.IsInstanceOfType (typeof (DD), o, "#a1");\r
+                       Assert.IsInstanceOfType (typeof (A), o, "#a2");\r
+                       Assert.IsInstanceOfType (typeof (B), o, "#a3");\r
+                       AssertHelper.IsNotInstanceOfType (typeof (CC), o, "#a4");\r
 \r
                        o = RemotingServices.Connect (typeof (DD), "tcp://localhost:3434/ff4.rem");\r
-                       Assert ("#d1", o is DD);\r
-                       Assert ("#d2", o is A);\r
-                       Assert ("#d3", o is B);\r
-                       Assert ("#d4", !(o is CC));\r
+                       Assert.IsInstanceOfType (typeof (DD), o, "#d1");\r
+                       Assert.IsInstanceOfType (typeof (A), o, "#d2");\r
+                       Assert.IsInstanceOfType (typeof (B), o, "#d3");\r
+                       AssertHelper.IsNotInstanceOfType (typeof (CC), o, "#d4");\r
 \r
                        o = RemotingServices.Connect (typeof (CC), "tcp://localhost:3434/ff5.rem");\r
-                       Assert ("#c1", !(o is DD));\r
-                       Assert ("#c2", o is A);\r
-                       Assert ("#c3", o is B);\r
-                       Assert ("#c4", o is CC);\r
+                       AssertHelper.IsNotInstanceOfType (typeof (DD), o, "#c1");\r
+                       Assert.IsInstanceOfType (typeof (A), o, "#c2");\r
+                       Assert.IsInstanceOfType (typeof (B), o, "#c3");\r
+                       Assert.IsInstanceOfType (typeof (CC), o, "#c4");\r
                }\r
                // Don't add any tests that must create channels\r
                // after ConnectProxyCast (), because this test calls\r
index 7a3834dd93c94c871a4c0cbd973d0ea053c1a6b6..cda78a94112d9d0ccba703a3516833a184940830 100644 (file)
@@ -38,9 +38,6 @@ using System.Runtime.Serialization;
 using System.ServiceModel;
 using NUnit.Framework;
 using NUnit.Framework.Constraints;
-#if !MOBILE
-using NUnit.Framework.SyntaxHelpers;
-#endif
 
 namespace MonoTests.System.Runtime.Serialization
 {
index 6a9b66a6485cfa4b050f788b6ced91d33a28ae9c..394d7d48ad056c2ba8e5be0c6362cf86e978b8b1 100644 (file)
@@ -44,7 +44,6 @@ using System.Xml.Serialization;
 using Microsoft.CSharp;
 using NUnit.Framework;
 using NUnit.Framework.Constraints;
-using NUnit.Framework.SyntaxHelpers;
 
 using QName = System.Xml.XmlQualifiedName;
 
@@ -67,7 +66,7 @@ namespace MonoTests.System.Runtime.Serialization
                        var type = exporter.Schemas.GlobalTypes [typeName];
 
                        Assert.That (type, Is.Not.Null, "#2");
-                       Assert.That (type, Is.InstanceOfType (typeof (XmlSchemaComplexType)), "#3");
+                       Assert.IsInstanceOfType (typeof (XmlSchemaComplexType), type, "#3");
 
                        var complex = (XmlSchemaComplexType)type;
                        Assert.That (complex.Annotation, Is.Null, "#4");
@@ -83,16 +82,16 @@ namespace MonoTests.System.Runtime.Serialization
                        Assert.That (list, Is.Not.Null, "#6");
                        Assert.That (list.Annotation, Is.Null, "#6a");
                        Assert.That (list.Name, Is.EqualTo ("list"), "#6b");
-                       Assert.That (list.ElementSchemaType, Is.InstanceOfType (typeof (XmlSchemaComplexType)), "#6c");
+                       Assert.IsInstanceOfType (typeof (XmlSchemaComplexType), list.ElementSchemaType, "#6c");
 
                        var listElement = (XmlSchemaComplexType)list.ElementSchemaType;
                        Assert.That (listElement.QualifiedName.Namespace, Is.EqualTo (MSArraysNamespace), "#6d");
                        Assert.That (listElement.QualifiedName.Name, Is.EqualTo ("ArrayOfint"), "#6e");
 
-                       Assert.That (listElement.Particle, Is.InstanceOfType (typeof(XmlSchemaSequence)), "#7");
+                       Assert.IsInstanceOfType (typeof(XmlSchemaSequence), listElement.Particle, "#7");
                        var listSeq = (XmlSchemaSequence)listElement.Particle;
                        Assert.That (listSeq.Items.Count, Is.EqualTo (1), "#7b");
-                       Assert.That (listSeq.Items[0], Is.InstanceOfType (typeof(XmlSchemaElement)), "#7c");
+                       Assert.IsInstanceOfType (typeof(XmlSchemaElement), listSeq.Items[0], "#7c");
                        Assert.That (listSeq.Annotation, Is.Null, "#7d");
 
                        var listSeqElement = (XmlSchemaElement)listSeq.Items[0];
@@ -103,16 +102,16 @@ namespace MonoTests.System.Runtime.Serialization
                        Assert.That (dict, Is.Not.Null, "#8");
                        Assert.That (dict.Annotation, Is.Null, "#8a");
                        Assert.That (dict.Name, Is.EqualTo ("dictionary"), "#8b");
-                       Assert.That (dict.ElementSchemaType, Is.InstanceOfType (typeof (XmlSchemaComplexType)), "#8c");
+                       Assert.IsInstanceOfType (typeof (XmlSchemaComplexType), dict.ElementSchemaType, "#8c");
                        
                        var dictElement = (XmlSchemaComplexType)dict.ElementSchemaType;
                        Assert.That (dictElement.QualifiedName.Namespace, Is.EqualTo (MSArraysNamespace), "#8d");
                        Assert.That (dictElement.QualifiedName.Name, Is.EqualTo ("ArrayOfKeyValueOfstringdouble"), "#8e");
 
-                       Assert.That (dictElement.Particle, Is.InstanceOfType (typeof(XmlSchemaSequence)), "#9");
+                       Assert.IsInstanceOfType (typeof(XmlSchemaSequence), dictElement.Particle, "#9");
                        var dictSeq = (XmlSchemaSequence)dictElement.Particle;
                        Assert.That (dictSeq.Items.Count, Is.EqualTo (1), "#9b");
-                       Assert.That (dictSeq.Items[0], Is.InstanceOfType (typeof(XmlSchemaElement)), "#9c");
+                       Assert.IsInstanceOfType (typeof(XmlSchemaElement), dictSeq.Items[0], "#9c");
                        Assert.That (dictSeq.Annotation, Is.Null, "#9d");
                        
                        var dictSeqElement = (XmlSchemaElement)dictSeq.Items[0];
@@ -124,7 +123,7 @@ namespace MonoTests.System.Runtime.Serialization
                        Assert.That (custom, Is.Not.Null, "#10");
                        Assert.That (custom.Annotation, Is.Null, "#10a");
                        Assert.That (custom.Name, Is.EqualTo ("customCollection"), "#10b");
-                       Assert.That (custom.ElementSchemaType, Is.InstanceOfType (typeof (XmlSchemaComplexType)), "#10c");
+                       Assert.IsInstanceOfType (typeof (XmlSchemaComplexType), custom.ElementSchemaType, "#10c");
                        
                        var customElement = (XmlSchemaComplexType)custom.ElementSchemaType;
                        var customEQN = customElement.QualifiedName;
@@ -132,10 +131,10 @@ namespace MonoTests.System.Runtime.Serialization
                        Assert.That (customEQN.Name.StartsWith ("XsdDataContractExporterTest2.MyCollectionOfstring", StringComparison.InvariantCultureIgnoreCase),
                                     Is.True, "#10e");
 
-                       Assert.That (customElement.Particle, Is.InstanceOfType (typeof(XmlSchemaSequence)), "#11");
+                       Assert.IsInstanceOfType (typeof(XmlSchemaSequence), customElement.Particle, "#11");
                        var customSeq = (XmlSchemaSequence)customElement.Particle;
                        Assert.That (customSeq.Items.Count, Is.EqualTo (1), "#11b");
-                       Assert.That (customSeq.Items[0], Is.InstanceOfType (typeof(XmlSchemaElement)), "#11c");
+                       Assert.IsInstanceOfType (typeof(XmlSchemaElement), customSeq.Items[0], "#11c");
                        Assert.That (customSeq.Annotation, Is.Null, "#11d");
                        
                        var customSeqElement = (XmlSchemaElement)customSeq.Items[0];
index bee52d3e4f896eb4a66a1f00b47fe8b14c7b33b4..7e86906afe3b68b833efa3f65e439a6c9ebdd379 100644 (file)
@@ -43,7 +43,6 @@ using System.Xml.Serialization;
 using Microsoft.CSharp;
 using NUnit.Framework;
 using NUnit.Framework.Constraints;
-using NUnit.Framework.SyntaxHelpers;
 
 using QName = System.Xml.XmlQualifiedName;
 
index e8e10533584f1277fdcfea277cf69ca0bdb89415..8527e5c313419206b5ee66e7b38885e7a449c393 100644 (file)
@@ -53,7 +53,7 @@ namespace System.ServiceModel.Channels
                {
                        FaultCode fc = null;
                        FaultReason fr = null;
-                       object details = null;
+                       string actor = null;
                        XmlDictionaryReader r = message.GetReaderAtBodyContents ();
                        r.ReadStartElement ("Fault", message.Version.Envelope.Namespace);
                        r.MoveToContent ();
@@ -66,11 +66,13 @@ namespace System.ServiceModel.Channels
                                case "faultstring":
                                        fr = new FaultReason (r.ReadElementContentAsString());
                                        break;
-                               case "detail":
-                                       return new XmlReaderDetailMessageFault (message, r, fc, fr, null, null);
                                case "faultactor":
+                                       actor = r.ReadElementContentAsString();
+                                       break;
+                               case "detail":
+                                       return new XmlReaderDetailMessageFault (message, r, fc, fr, actor, null);
                                default:
-                                       throw new NotImplementedException ();
+                                       throw new XmlException (String.Format ("Unexpected node {0} name {1}", r.NodeType, r.Name));
                                }
                                r.MoveToContent ();
                        }
@@ -79,9 +81,7 @@ namespace System.ServiceModel.Channels
                        if (fr == null)
                                throw new XmlException ("Reason is missing in the Fault message");
 
-                       if (details == null)
-                               return CreateFault (fc, fr);
-                       return CreateFault (fc, fr, details);
+                       return new SimpleMessageFault (fc, fr, false, null, null, actor, null);
                }
 
                static MessageFault CreateFault12 (Message message, int maxBufferSize)
index 65b5c8cf38ae6913b2482b54609ecc8ee45064e4..f1a7ca308c058f0ec29cfea5e1516b933687a712 100644 (file)
@@ -364,8 +364,11 @@ namespace System.ServiceModel.Dispatcher
 
                        public void Start ()
                        {
-                               if (loop_thread == null)
+                               if (loop_thread == null) {
                                        loop_thread = new Thread (new ThreadStart (Loop));
+                                       loop_thread.IsBackground = true;
+                               }
+
                                loop_thread.Start ();
                        }
 
@@ -425,8 +428,10 @@ namespace System.ServiceModel.Dispatcher
                                        Logger.Warning (String.Format ("Channel listener '{0}' is not closed. Aborting.", owner.Listener.GetType ()));
                                        owner.Listener.Abort ();
                                }
-                               if (loop_thread != null && loop_thread.IsAlive)
-                                       loop_thread.Abort ();
+                               if (loop_thread != null && loop_thread.IsAlive) {
+                                       if (!loop_thread.Join (500))
+                                               loop_thread.Abort ();
+                               }
                                loop_thread = null;
                        }
 
index d06cb33fe21c43bca6002a04358d3c9f0c28bbe9..c788a402138e04da469f0701d7f16f5e10fdcd91 100644 (file)
@@ -1,3 +1,4 @@
+../../test-helpers/NunitHelpers.cs
 NUnitMoonHelper.cs
 FeatureBased/Features.Client/AsyncCallTesterProxy.cs
 FeatureBased/Features.Client/AsyncPatternServer.cs
index b85b9f02f4cabc7f0e9893114b241ac472fe3dd0..8942c7abf32b4d63e8999cb126f4e63aca43b57a 100644 (file)
@@ -37,7 +37,6 @@ using System.ServiceModel.Channels;
 using System.ServiceModel.Description;
 using NUnit.Framework;
 using NUnit.Framework.Constraints;
-using NUnit.Framework.SyntaxHelpers;
 
 using QName = System.Xml.XmlQualifiedName;
 using WS = System.Web.Services.Description;
@@ -91,7 +90,7 @@ namespace MonoTests.System.ServiceModel.MetadataTests {
                static void CheckSoapBinding (object extension, string transport, TestLabel label)
                {
                        label.EnterScope ("soap");
-                       Assert.That (extension, Is.InstanceOfType (typeof (WS.SoapBinding)), label.Get ());
+                       Assert.That (extension, Is.AssignableTo<WS.SoapBinding>(), label.Get ());
                        var soap = (WS.SoapBinding)extension;
                        Assert.That (soap.Style, Is.EqualTo (WS.SoapBindingStyle.Document), label.Get ());
                        Assert.That (soap.Transport, Is.EqualTo (transport), label.Get ());
@@ -107,9 +106,9 @@ namespace MonoTests.System.ServiceModel.MetadataTests {
                        label.EnterScope ("http");
 
                        if (security == BasicHttpSecurityMode.Message) {
-                               Assert.That (binding, Is.InstanceOfType (typeof(CustomBinding)), label.Get ());
+                               Assert.IsInstanceOfType (typeof(CustomBinding), binding, label.Get ());
                        } else {
-                               Assert.That (binding, Is.InstanceOfType (typeof(BasicHttpBinding)), label.Get ());
+                               Assert.IsInstanceOfType (typeof(BasicHttpBinding), binding, label.Get ());
                                var basicHttp = (BasicHttpBinding)binding;
                                Assert.That (basicHttp.EnvelopeVersion, Is.EqualTo (EnvelopeVersion.Soap11), label.Get ());
                                Assert.That (basicHttp.MessageVersion, Is.EqualTo (MessageVersion.Soap11), label.Get ());
@@ -157,7 +156,7 @@ namespace MonoTests.System.ServiceModel.MetadataTests {
                        label.EnterScope ("text");
                        if (encoding == WSMessageEncoding.Text) {
                                Assert.That (textElement, Is.Not.Null, label.Get ());
-                               Assert.That (textElement.WriteEncoding, Is.InstanceOfType (typeof(UTF8Encoding)), label.Get ());
+                               Assert.IsInstanceOfType (typeof(UTF8Encoding), textElement.WriteEncoding, label.Get ());
                        } else {
                                Assert.That (textElement, Is.Null, label.Get ());
                        }
@@ -409,9 +408,9 @@ namespace MonoTests.System.ServiceModel.MetadataTests {
                {
                        label.EnterScope ("net-tcp");
                        if (security == SecurityMode.Message) {
-                               Assert.That (binding, Is.InstanceOfType (typeof(CustomBinding)), label.Get ());
+                               Assert.IsInstanceOfType (typeof(CustomBinding), binding, label.Get ());
                        } else {
-                               Assert.That (binding, Is.InstanceOfType (typeof(NetTcpBinding)), label.Get ());
+                               Assert.IsInstanceOfType (typeof(NetTcpBinding), binding, label.Get ());
                                var netTcp = (NetTcpBinding)binding;
                                Assert.That (netTcp.EnvelopeVersion, Is.EqualTo (EnvelopeVersion.Soap12), label.Get ());
                                Assert.That (netTcp.MessageVersion, Is.EqualTo (MessageVersion.Soap12WSAddressing10), label.Get ());
@@ -751,7 +750,7 @@ namespace MonoTests.System.ServiceModel.MetadataTests {
                        foreach (var node in all.ChildNodes) {
                                if (node is XmlWhitespace)
                                        continue;
-                               Assert.That (node, Is.InstanceOfType (typeof (XmlElement)), label.ToString ());
+                               Assert.IsInstanceOfType (typeof (XmlElement), node, label.ToString ());
                                collection.Add ((XmlElement)node);
                        }
                        label.LeaveScope ();
@@ -789,7 +788,7 @@ namespace MonoTests.System.ServiceModel.MetadataTests {
                        label.EnterScope ("extensions");
                        Assert.That (op.Extensions, Is.Not.Null, label.Get ());
                        Assert.That (op.Extensions.Count, Is.EqualTo (1), label.Get ());
-                       Assert.That (op.Extensions [0], Is.InstanceOfType (typeof (WS.SoapOperationBinding)), label.Get ());
+                       Assert.That (op.Extensions [0], Is.AssignableTo<WS.SoapOperationBinding>(), label.Get ());
                        var soap = (WS.SoapOperationBinding)op.Extensions [0];
                        TestSoap (soap, soap12, label);
                        label.LeaveScope ();
@@ -821,7 +820,7 @@ namespace MonoTests.System.ServiceModel.MetadataTests {
                        Assert.That (binding.ExtensibleAttributes, Is.Null, label.Get ());
                        Assert.That (binding.Extensions, Is.Not.Null, label.Get ());
                        Assert.That (binding.Extensions.Count, Is.EqualTo (1), label.Get ());
-                       Assert.That (binding.Extensions [0], Is.InstanceOfType (typeof (WS.SoapBodyBinding)), label.Get ());
+                       Assert.That (binding.Extensions [0], Is.AssignableTo<WS.SoapBodyBinding> (), label.Get ());
                        var body = (WS.SoapBodyBinding)binding.Extensions [0];
                        TestSoapBody (body, soap12, label);
                        label.LeaveScope ();
index 3bd64b70dedce02d94b06b2bc65c923ab133c830..a4cbb9cd3eeaec39c008895366358e6a1369a4ce 100644 (file)
@@ -36,7 +36,6 @@ using WS = System.Web.Services.Description;
 
 using NUnit.Framework;
 using NUnit.Framework.Constraints;
-using NUnit.Framework.SyntaxHelpers;
 
 namespace MonoTests.System.ServiceModel.MetadataTests {
 
index f43655c573616811d5c737923109c124ff68edec..6262109c1169a09a5cd0235f4a543030c185db48 100644 (file)
@@ -34,7 +34,6 @@ using System.ServiceModel.Channels;
 using System.ServiceModel.Description;
 using NUnit.Framework;
 using NUnit.Framework.Constraints;
-using NUnit.Framework.SyntaxHelpers;
 
 using WS = System.Web.Services.Description;
 
index 3a92db121d5f92b59acc561e9478754899d6638b..4da65c703a524f6083cc7aaac19ca97f9d44f09c 100644 (file)
@@ -34,7 +34,6 @@ using System.ServiceModel.Channels;
 using System.ServiceModel.Description;
 using NUnit.Framework;
 using NUnit.Framework.Constraints;
-using NUnit.Framework.SyntaxHelpers;
 
 namespace MonoTests.System.ServiceModel.MetadataTests {
        
index f6656e5c7d9603377dd5858ecc08c32db865c4e8..1e5c270d988b57f7c15dab049c81c37097cf54a5 100644 (file)
@@ -34,7 +34,6 @@ using System.ServiceModel.Channels;
 using System.ServiceModel.Description;
 using NUnit.Framework;
 using NUnit.Framework.Constraints;
-using NUnit.Framework.SyntaxHelpers;
 
 using WS = System.Web.Services.Description;
 
index 19560b9315095ec4183d79f33e2af1de49fe1114..2acf8f04b81cbaca4b5eeff56d230438f4853c66 100644 (file)
@@ -34,7 +34,6 @@ using System.ServiceModel.Description;
 using System.Text;
 using NUnit.Framework;
 using NUnit.Framework.Constraints;
-using NUnit.Framework.SyntaxHelpers;
 
 using TextElement = System.ServiceModel.Channels.TextMessageEncodingBindingElement;
 using BinaryElement = System.ServiceModel.Channels.BinaryMessageEncodingBindingElement;
index eae3d7ca74b439878c6a87619bd791926cb0cfcf..5c73c059324be5ac4dc2198f80e65d3454e77a59 100644 (file)
@@ -71,6 +71,7 @@ namespace MonoTests.System.ServiceModel.Channels
     <s:Fault>
       <faultcode>a:ActionNotSupported</faultcode>
       <faultstring xml:lang='en-US'>some error</faultstring>
+      <faultactor>Random</faultactor>
     </s:Fault>
   </s:Body>
 </s:Envelope>";
index 6a85bfc9e8d22ac0068c5de552aa2012bbecaf92..23c4a7ed6b86a121e5d3aaf0a8fd216fca5748e0 100644 (file)
@@ -1,3 +1,4 @@
+../../test-helpers/NunitHelpers.cs
 System.ServiceProcess/ServiceBaseTest.cs
 System.ServiceProcess/ServiceControllerTest.cs
 System.ServiceProcess/ServiceControllerPermissionAttributeTest.cs
index bec9f30a1884947be265b146bcbe9a14ad3d76e3..46953497fd3b0669a9f1d3339492d34c64df71ba 100644 (file)
@@ -131,7 +131,7 @@ namespace MonoTests.System.Threading.Tasks.Dataflow {
                        Assert.IsTrue (transform.Post (1));
                        Assert.IsTrue (transform.Post (2));
 
-                       Assert.GreaterOrEqual (scheduler.ExecuteAll (), 1);
+                       AssertHelper.GreaterOrEqual (scheduler.ExecuteAll (), 1);
 
                        Assert.AreEqual (2, Volatile.Read (ref n));
                }
@@ -154,7 +154,7 @@ namespace MonoTests.System.Threading.Tasks.Dataflow {
                        Assert.IsTrue (transform.Post (1));
                        Assert.IsTrue (transform.Post (2));
 
-                       Assert.GreaterOrEqual (scheduler.ExecuteAll (), 1);
+                       AssertHelper.GreaterOrEqual (scheduler.ExecuteAll (), 1);
 
                        Assert.AreEqual (2, Volatile.Read (ref n));
                }
@@ -177,7 +177,7 @@ namespace MonoTests.System.Threading.Tasks.Dataflow {
 
                        Assert.IsFalse (transform.Post (101));
 
-                       Assert.GreaterOrEqual (scheduler.ExecuteAll (), 1);
+                       AssertHelper.GreaterOrEqual (scheduler.ExecuteAll (), 1);
 
                        Assert.IsFalse (transform.Post (102));
 
index f897f06e23ec0462959abcb771decc277aa2ed6f..65ed145d72c40b9180e7655942714c806f95108e 100644 (file)
@@ -128,7 +128,7 @@ namespace MonoTests.System.Threading.Tasks.Dataflow {
 
                        Assert.IsNotNull (ex);
                        Assert.IsNotNull (ex.InnerException);
-                       Assert.IsInstanceOfType (typeof(OperationCanceledException),
+                       Assert.IsInstanceOfType (typeof(TaskCanceledException),
                                ex.InnerException);
                        Assert.IsTrue (task.IsCompleted);
                        Assert.AreEqual (TaskStatus.Canceled, task.Status);
index 6d87932058401cac0c2528c0ed6da421068ea900..087385c2ffc4f9e009a6d4815195fc2a9229cdc6 100644 (file)
@@ -90,7 +90,7 @@ namespace MonoTests.System.Threading.Tasks.Dataflow {
                                var queue = new ConcurrentQueue<Tuple<int, int>> ();
                                var block = factory (queue);
 
-                               Assert.IsEmpty (queue);
+                               CollectionAssert.IsEmpty (queue);
 
                                for (int i = 0; i < 100; i++)
                                        block.Post (i);
@@ -170,15 +170,15 @@ namespace MonoTests.System.Threading.Tasks.Dataflow {
 
                                options = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 2 };
                                foreach (var taskIds in GetTaskIdsForExecutionsOptions (options))
-                                       Assert.LessOrEqual (CalculateDegreeOfParallelism (taskIds), 2);
+                                       AssertHelper.LessOrEqual (CalculateDegreeOfParallelism (taskIds), 2);
 
                                options = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 4 };
                                foreach (var taskIds in GetTaskIdsForExecutionsOptions (options))
-                                       Assert.LessOrEqual (CalculateDegreeOfParallelism (taskIds), 4);
+                                       AssertHelper.LessOrEqual (CalculateDegreeOfParallelism (taskIds), 4);
 
                                options = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = -1 };
                                foreach (var taskIds in GetTaskIdsForExecutionsOptions (options))
-                                       Assert.LessOrEqual (CalculateDegreeOfParallelism (taskIds), taskIds.Length);
+                                       AssertHelper.LessOrEqual (CalculateDegreeOfParallelism (taskIds), taskIds.Length);
                        }
                }
 
@@ -187,7 +187,7 @@ namespace MonoTests.System.Threading.Tasks.Dataflow {
                {
                        var options = new ExecutionDataflowBlockOptions ();
                        foreach (var taskIds in GetTaskIdsForExecutionsOptions (options))
-                               Assert.GreaterOrEqual (taskIds.Distinct ().Count (), 1);
+                               AssertHelper.GreaterOrEqual (taskIds.Distinct ().Count (), 1);
 
                        options = new ExecutionDataflowBlockOptions { MaxMessagesPerTask = 1 };
                        foreach (var taskIds in GetTaskIdsForExecutionsOptions (options))
@@ -195,11 +195,11 @@ namespace MonoTests.System.Threading.Tasks.Dataflow {
 
                        options = new ExecutionDataflowBlockOptions { MaxMessagesPerTask = 2 };
                        foreach (var taskIds in GetTaskIdsForExecutionsOptions (options))
-                               Assert.GreaterOrEqual (taskIds.Distinct ().Count (), taskIds.Length / 2);
+                               AssertHelper.GreaterOrEqual (taskIds.Distinct ().Count (), taskIds.Length / 2);
 
                        options = new ExecutionDataflowBlockOptions { MaxMessagesPerTask = 4 };
                        foreach (var taskIds in GetTaskIdsForExecutionsOptions (options))
-                               Assert.GreaterOrEqual (taskIds.Distinct ().Count (), taskIds.Length / 4);
+                               AssertHelper.GreaterOrEqual (taskIds.Distinct ().Count (), taskIds.Length / 4);
                }
 
                [Test]
index f619c25efb836f13b1917d0271c2844403b5ec34..67e3e1a64087ed1f59f6793603081d499d3dc91c 100644 (file)
@@ -1,3 +1,4 @@
+../../test-helpers/NunitHelpers.cs
 ../../System.Web/Test/mainsoft/MainsoftWebTest/HtmlAgilityPack/crc32.cs
 ../../System.Web/Test/mainsoft/MainsoftWebTest/HtmlAgilityPack/Header.cs
 ../../System.Web/Test/mainsoft/MainsoftWebTest/HtmlAgilityPack/HtmlAttribute.cs
@@ -71,7 +72,6 @@ Common/FooWithToString.cs
 Common/ITestDataContext.cs
 Common/KnownResponseHeader.cs
 Common/MiscExtensions.cs
-Common/Mocks.cs
 Common/MyDynamicDataRouteHandler.cs
 Common/MyHttpContextWrapper.cs
 Common/MyHttpRequestWrapper.cs
diff --git a/mcs/class/System.Web.DynamicData/Test/Common/Mocks.cs b/mcs/class/System.Web.DynamicData/Test/Common/Mocks.cs
deleted file mode 100644 (file)
index 5010769..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Web;
-
-using NUnit.Framework;
-using NUnit.Mocks;
-
-namespace MonoTests.Common
-{
-    static class Mocks
-    {
-     
-    }
-}
index cbd6a10a5331af005b1c8f7125f438a3818a7015..7f2d214ea49ef93befc1f62dec1af8d97e6d3357 100644 (file)
@@ -52,7 +52,6 @@ using System.Web.UI.WebControls;
 using System.IO;
 
 using NUnit.Framework;
-using NUnit.Mocks;
 using MonoTests.stand_alone.WebHarness;
 using MonoTests.SystemWeb.Framework;
 using MonoTests.Common;
index b144e17e4ed64f676c0b9b7d9895ec0da0153d6a..b44c8bd9327ed8fcedede646fba2d66487cef16e 100644 (file)
@@ -47,7 +47,6 @@ using System.Web.DynamicData.ModelProviders;
 using System.Web.Routing;
 
 using NUnit.Framework;
-using NUnit.Mocks;
 using MonoTests.stand_alone.WebHarness;
 using MonoTests.SystemWeb.Framework;
 using MonoTests.Common;
index 3954861970bb5b674e8c4d44ed149a535c14ceda..1151fb86612a273fe4d427e4c80eb0f29147ae99 100644 (file)
@@ -49,7 +49,6 @@ using System.Web.DynamicData.ModelProviders;
 using System.Web.Routing;
 
 using NUnit.Framework;
-using NUnit.Mocks;
 using MonoTests.stand_alone.WebHarness;
 using MonoTests.SystemWeb.Framework;
 using MonoTests.Common;
index 6f5f4fdd3dc22f3f4879dad9fbec0357577deba5..0884c7a5cef1aa91ea4f05625d08844f98d1921c 100644 (file)
@@ -52,7 +52,6 @@ using System.Web.UI.WebControls;
 using System.IO;
 
 using NUnit.Framework;
-using NUnit.Mocks;
 using MonoTests.stand_alone.WebHarness;
 using MonoTests.SystemWeb.Framework;
 using MonoTests.Common;
index 4398b8bf4f5e42b01efb1a3b3c26b6736fbc2f97..8362f3b6a96ccebb306b4c78c13b6a462737cfec 100644 (file)
@@ -52,7 +52,6 @@ using System.Web.UI.WebControls;
 using System.IO;
 
 using NUnit.Framework;
-using NUnit.Mocks;
 using MonoTests.stand_alone.WebHarness;
 using MonoTests.SystemWeb.Framework;
 using MonoTests.Common;
@@ -647,7 +646,7 @@ namespace MonoTests.System.Web.DynamicData
                        // Custom with UIHint attribute
                        mc = t.GetColumn ("CustomColumn2");
                        Assert.IsNotNull (mc.UIHint, "#A2");
-                       Assert.Greater (mc.UIHint.Length, 0, "#A2-1");
+                       AssertHelper.Greater (mc.UIHint.Length, 0, "#A2-1");
 
                        // Proves that UIHint on the column is not used, just the uiHint argument
                        AssertExtensions.Throws<InvalidOperationException> (() => {
@@ -669,7 +668,7 @@ namespace MonoTests.System.Web.DynamicData
                        // Custom with UIHint attribute
                        mc = t.GetColumn ("CustomColumn4");
                        Assert.IsNotNull (mc.UIHint, "#A4");
-                       Assert.Greater (mc.UIHint.Length, 0, "#A4-1");
+                       AssertHelper.Greater (mc.UIHint.Length, 0, "#A4-1");
 
                        // Proves that UIHint on the column is not used, just the uiHint argument
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, null), "#A4-2");
@@ -686,7 +685,7 @@ namespace MonoTests.System.Web.DynamicData
 
                        mc = t.GetColumn ("DateTimeColumn2");
                        Assert.IsNotNull (mc.UIHint, "#B2");
-                       Assert.Greater (mc.UIHint.Length, 0, "#B2-1");
+                       AssertHelper.Greater (mc.UIHint.Length, 0, "#B2-1");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "DateTime.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, null), "#B2-3");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "DateTime.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, String.Empty), "#B2-4");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "DateTime.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, "Boolean.ascx"), "#B2-5");
@@ -701,7 +700,7 @@ namespace MonoTests.System.Web.DynamicData
 
                        mc = t.GetColumn ("DateColumn2");
                        Assert.IsNotNull (mc.UIHint, "#C2");
-                       Assert.Greater (mc.UIHint.Length, 0, "#C2-1");
+                       AssertHelper.Greater (mc.UIHint.Length, 0, "#C2-1");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, null), "#C2-3");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, String.Empty), "#C2-4");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, "Boolean.ascx"), "#C2-5");
@@ -715,7 +714,7 @@ namespace MonoTests.System.Web.DynamicData
 
                        mc = t.GetColumn ("DateColumn4");
                        Assert.IsNotNull (mc.UIHint, "#C4");
-                       Assert.Greater (mc.UIHint.Length, 0, "#C4-1");
+                       AssertHelper.Greater (mc.UIHint.Length, 0, "#C4-1");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, null), "#C4-3");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, String.Empty), "#C4-4");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, "Boolean.ascx"), "#C4-5");
@@ -730,7 +729,7 @@ namespace MonoTests.System.Web.DynamicData
 
                        mc = t.GetColumn ("TimeColumn2");
                        Assert.IsNotNull (mc.UIHint, "#D2");
-                       Assert.Greater (mc.UIHint.Length, 0, "#D2-1");
+                       AssertHelper.Greater (mc.UIHint.Length, 0, "#D2-1");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, null), "#D2-3");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, String.Empty), "#D2-4");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, "Boolean.ascx"), "#D2-5");
@@ -745,7 +744,7 @@ namespace MonoTests.System.Web.DynamicData
 
                        mc = t.GetColumn ("DurationColumn2");
                        Assert.IsNotNull (mc.UIHint, "#E2");
-                       Assert.Greater (mc.UIHint.Length, 0, "#E2-1");
+                       AssertHelper.Greater (mc.UIHint.Length, 0, "#E2-1");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, null), "#E2-3");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, String.Empty), "#E2-4");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, "Boolean.ascx"), "#E2-5");
@@ -760,7 +759,7 @@ namespace MonoTests.System.Web.DynamicData
 
                        mc = t.GetColumn ("PhoneNumberColumn2");
                        Assert.IsNotNull (mc.UIHint, "#F2");
-                       Assert.Greater (mc.UIHint.Length, 0, "#F2-1");
+                       AssertHelper.Greater (mc.UIHint.Length, 0, "#F2-1");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, null), "#F2-3");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, String.Empty), "#F2-4");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, "Boolean.ascx"), "#F2-5");
@@ -775,7 +774,7 @@ namespace MonoTests.System.Web.DynamicData
 
                        mc = t.GetColumn ("CurrencyColumn2");
                        Assert.IsNotNull (mc.UIHint, "#G2");
-                       Assert.Greater (mc.UIHint.Length, 0, "#G2-1");
+                       AssertHelper.Greater (mc.UIHint.Length, 0, "#G2-1");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, null), "#G2-3");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, String.Empty), "#G2-4");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, "Boolean.ascx"), "#G2-5");
@@ -790,7 +789,7 @@ namespace MonoTests.System.Web.DynamicData
 
                        mc = t.GetColumn ("TextColumn2");
                        Assert.IsNotNull (mc.UIHint, "#H2");
-                       Assert.Greater (mc.UIHint.Length, 0, "#H2-1");
+                       AssertHelper.Greater (mc.UIHint.Length, 0, "#H2-1");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, null), "#H2-3");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, String.Empty), "#H2-4");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, "Boolean.ascx"), "#H2-5");
@@ -805,7 +804,7 @@ namespace MonoTests.System.Web.DynamicData
 
                        mc = t.GetColumn ("HtmlColumn2");
                        Assert.IsNotNull (mc.UIHint, "#I2");
-                       Assert.Greater (mc.UIHint.Length, 0, "#I2-1");
+                       AssertHelper.Greater (mc.UIHint.Length, 0, "#I2-1");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, null), "#I2-3");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, String.Empty), "#I2-4");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, "Boolean.ascx"), "#I2-5");
@@ -820,7 +819,7 @@ namespace MonoTests.System.Web.DynamicData
 
                        mc = t.GetColumn ("MultilineTextColumn2");
                        Assert.IsNotNull (mc.UIHint, "#J2");
-                       Assert.Greater (mc.UIHint.Length, 0, "#J2-1");
+                       AssertHelper.Greater (mc.UIHint.Length, 0, "#J2-1");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, null), "#J2-3");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, String.Empty), "#J2-4");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, "Boolean.ascx"), "#J2-5");
@@ -835,7 +834,7 @@ namespace MonoTests.System.Web.DynamicData
 
                        mc = t.GetColumn ("EmailAddressColumn2");
                        Assert.IsNotNull (mc.UIHint, "#K2");
-                       Assert.Greater (mc.UIHint.Length, 0, "#K2-1");
+                       AssertHelper.Greater (mc.UIHint.Length, 0, "#K2-1");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, null), "#K2-3");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, String.Empty), "#K2-4");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, "Boolean.ascx"), "#K2-5");
@@ -850,7 +849,7 @@ namespace MonoTests.System.Web.DynamicData
 
                        mc = t.GetColumn ("PasswordColumn2");
                        Assert.IsNotNull (mc.UIHint, "#L2");
-                       Assert.Greater (mc.UIHint.Length, 0, "#L2-1");
+                       AssertHelper.Greater (mc.UIHint.Length, 0, "#L2-1");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, null), "#L2-3");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, String.Empty), "#L2-4");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, "Boolean.ascx"), "#L2-5");
@@ -865,7 +864,7 @@ namespace MonoTests.System.Web.DynamicData
 
                        mc = t.GetColumn ("UrlColumn2");
                        Assert.IsNotNull (mc.UIHint, "#M2");
-                       Assert.Greater (mc.UIHint.Length, 0, "#M2-1");
+                       AssertHelper.Greater (mc.UIHint.Length, 0, "#M2-1");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, null), "#M2-3");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, String.Empty), "#M2-4");
                        Assert.AreEqual (ftf.TemplateFolderVirtualPath + "Text.ascx", ftf.GetFieldTemplateVirtualPath (mc, DataBoundControlMode.ReadOnly, "Boolean.ascx"), "#M2-5");
index 46de57ad76c287813c64267eddba63dfca055946..423237d1ec0fa6c95cc6227714325f5c37d3bee7 100644 (file)
@@ -52,7 +52,6 @@ using System.Web.UI.WebControls;
 using System.IO;
 
 using NUnit.Framework;
-using NUnit.Mocks;
 using MonoTests.stand_alone.WebHarness;
 using MonoTests.SystemWeb.Framework;
 using MonoTests.Common;
index e2e1e24b1548853ef3371778c24f9b72d11284fe..17766eae14e236c4b4504c655c5e74893b112581 100644 (file)
@@ -47,7 +47,6 @@ using System.Web.DynamicData.ModelProviders;
 using System.Web.Routing;
 
 using NUnit.Framework;
-using NUnit.Mocks;
 using MonoTests.stand_alone.WebHarness;
 using MonoTests.SystemWeb.Framework;
 using MonoTests.Common;
index fe43459bfc717f97c93a55496e08f2494c92474b..ed33152de0d52e743bc7730e216bfd4b764ccf33 100644 (file)
@@ -48,7 +48,6 @@ using System.Web.DynamicData.ModelProviders;
 using System.Web.Routing;
 
 using NUnit.Framework;
-using NUnit.Mocks;
 using MonoTests.stand_alone.WebHarness;
 using MonoTests.SystemWeb.Framework;
 using MonoTests.Common;
index 76d528e4e790089e3eb0eddd9456c36a1a06858d..b51fb6d731401e2d57603bd85814325ed1a9eec9 100644 (file)
@@ -49,7 +49,6 @@ using System.Web.Routing;
 using System.Web.UI.WebControls;
 
 using NUnit.Framework;
-using NUnit.Mocks;
 using MonoTests.stand_alone.WebHarness;
 using MonoTests.SystemWeb.Framework;
 using MonoTests.Common;
index 09bd670bd4d091650ebc39a84c89dd0aecf45ae7..47a1fa4a8dedb246bb0f5720262453c766a8b67f 100644 (file)
@@ -1,3 +1,4 @@
+../../test-helpers/NunitHelpers.cs
 Test/standalone-tests/Consts.cs
 Test/standalone-tests/Locations.cs
 Test/standalone-tests/OutputCacheProvider.cs
index 4416f5a698b9262d036092092c23f1b41e3585a4..70593c25d06a0d72c3314d40fad9d64d4688b7a0 100644 (file)
@@ -1,3 +1,4 @@
+../../test-helpers/NunitHelpers.cs
 ../../System.Web.DynamicData/Test/Common/AssertExtensions.cs
 mainsoft/MainsoftWebTest/HtmlAgilityPack/AssemblyInfo.cs
 mainsoft/MainsoftWebTest/HtmlAgilityPack/crc32.cs
index 22f3996e76bde65974fdc6873edf26fa350da26f..e240e4355ff5dc3e47b72d8ef5ec25369c05886e 100644 (file)
@@ -77,13 +77,13 @@ namespace MonoTests.System.Web.Hosting {
                        Assert.IsNull (HostingEnvironment.InitializationException, "During:InitializationException");
                        Assert.IsTrue (HostingEnvironment.IsHosted, "During:IsHosted");
                        Assert.IsNotNull (HostingEnvironment.ApplicationID, "During:ApplicationID:Null");
-                       Assert.IsNotEmpty (HostingEnvironment.ApplicationID, "During:ApplicationID:Empty");
+                       AssertHelper.IsNotEmpty (HostingEnvironment.ApplicationID, "During:ApplicationID:Empty");
                        Assert.IsNotNull (HostingEnvironment.ApplicationPhysicalPath, "During:ApplicationPhysicalPath:Null");
-                       Assert.IsNotEmpty (HostingEnvironment.ApplicationPhysicalPath, "During:ApplicationPhysicalPath:Empty");
+                       AssertHelper.IsNotEmpty (HostingEnvironment.ApplicationPhysicalPath, "During:ApplicationPhysicalPath:Empty");
                        Assert.IsNotNull (HostingEnvironment.ApplicationVirtualPath, "During:ApplicationVirtualPath:Null");
-                       Assert.IsNotEmpty (HostingEnvironment.ApplicationVirtualPath, "During:ApplicationVirtualPath:Empty");
+                       AssertHelper.IsNotEmpty (HostingEnvironment.ApplicationVirtualPath, "During:ApplicationVirtualPath:Empty");
                        Assert.IsNotNull (HostingEnvironment.SiteName, "During:SiteName:Null");
-                       Assert.IsNotEmpty (HostingEnvironment.SiteName, "During:SiteName:Empty");
+                       AssertHelper.IsNotEmpty (HostingEnvironment.SiteName, "During:SiteName:Empty");
                        Assert.IsNotNull (HostingEnvironment.Cache, "During:Cache");
                        Assert.AreEqual (ApplicationShutdownReason.None, HostingEnvironment.ShutdownReason, "During:ShutdownReason");
                        Assert.IsNotNull (HostingEnvironment.VirtualPathProvider, "During:VirtualPathProvider");
index 2ce8621aec4781a1245a02df3114d4f7c8d3b030..0342a707978e4971ebe73e3217ea353d9be06a79 100644 (file)
@@ -547,7 +547,7 @@ namespace MonoTests.System.Web {
 
                        KnownResponseHeader known;
 
-                       Assert.LessOrEqual (1, f.KnownResponseHeaders.Count, "#B1");
+                       AssertHelper.LessOrEqual (1, f.KnownResponseHeaders.Count, "#B1");
 
                        known = (KnownResponseHeader)f.KnownResponseHeaders ["Content-Type"];
                        Assert.AreEqual (HttpWorkerRequest.HeaderContentType, known.Index, "#B2");
@@ -571,7 +571,7 @@ namespace MonoTests.System.Web {
 
                        KnownResponseHeader known;
 
-                       Assert.LessOrEqual (1, f.KnownResponseHeaders.Count, "#B1");
+                       AssertHelper.LessOrEqual (1, f.KnownResponseHeaders.Count, "#B1");
 
                        known = (KnownResponseHeader)f.KnownResponseHeaders ["Content-Type"];
                        Assert.AreEqual (HttpWorkerRequest.HeaderContentType, known.Index, "#B2");
index 52439e975abadcb7073dca94f9ae0f42e9ef4f51..51742ec6bc9d739aa44ef9b69d317e285427df3a 100644 (file)
@@ -55,7 +55,6 @@ namespace MonoTests.System.Web
                [Test]
                [Category ("NunitWeb")]
                [Ignore ("Pending fix for bug 351878")]
-               [Explicit]
                public void UnloadAppDomain100Times () 
                {
                        for (int i = 0; i < 100; i++)
index 23487dacb07c844cc0fc2046b631820a1ba1d34b..73c5c75bb2c29ba36d618e41e1da91a03cf51702 100644 (file)
@@ -148,7 +148,7 @@ namespace MonoTests.System.Web
                        provider.DoAddNode (node, rootNode);
 
                        Assert.IsNotNull (provider.CallTrace, "#A1");
-                       Assert.Greater (provider.CallTrace.Length, 1, "#A1-1");
+                       AssertHelper.Greater (provider.CallTrace.Length, 1, "#A1-1");
                        Assert.AreEqual (provider.CallTrace[0].Name, "BuildSiteMap", "#A1-2");
                }
 
@@ -247,7 +247,7 @@ namespace MonoTests.System.Web
                        Assert.IsNotNull (provider.RootNode, "#A1");
                        Assert.AreEqual (provider.RootNode.Provider, provider, "#A2");
                        Assert.IsNotNull (provider.CallTrace, "#A3");
-                       Assert.Greater (provider.CallTrace.Length, 1, "#A3-1");
+                       AssertHelper.Greater (provider.CallTrace.Length, 1, "#A3-1");
                        Assert.AreEqual ("BuildSiteMap", provider.CallTrace[0].Name, "#A3-2");
                        Assert.AreEqual ("get_RootNode", provider.CallTrace[1].Name, "#A3-3");
                }
index f336b1537be36e1a8975e7fe1d530d1e8fe23f6f..884953ac3dd9e06e8d460a54b70cbc646b84ebbd 100644 (file)
@@ -1,3 +1,4 @@
+../../test-helpers/NunitHelpers.cs
 ../../../build/common/Consts.cs
 System.Windows.Forms/ApplicationTest.cs
 System.Windows.Forms/AutoCompleteStringCollectionTest.cs
index d0e3fc1bd3d8315e2dfd49e19881ce93b76d0590..0414fa18e710249b0d7c4f2a74448c8cfb4bce69 100644 (file)
@@ -47,7 +47,7 @@ namespace MonoTests.System.Resources {
 
                        Assert.IsNotNull (returnedNode, "#A1");
                        object val = returnedNode.GetValue (new ReturnSerializableSubClassITRS ());
-                       Assert.IsNotInstanceOfType (typeof (serializableSubClass), val, "#A2");
+                       AssertHelper.IsNotInstanceOfType (typeof (serializableSubClass), val, "#A2");
                        Assert.IsInstanceOfType (typeof (serializable), val, "#A3");
                }
 
@@ -84,7 +84,7 @@ namespace MonoTests.System.Resources {
                        node = GetNodeFileRefToSerializable ("ser.bbb",true);
 
                        object val = node.GetValue (new ReturnSerializableSubClassITRS ());
-                       Assert.IsNotInstanceOfType (typeof (serializableSubClass), val, "#A1");
+                       AssertHelper.IsNotInstanceOfType (typeof (serializableSubClass), val, "#A1");
                        Assert.IsInstanceOfType (typeof (serializable), val, "#A2");
                }
 
index 8ca5f4eb574d131270e3a12297929e39a02f9f86..3c0fc3beaaff338c0fa31e85244079d349c433da 100644 (file)
@@ -90,7 +90,7 @@ namespace MonoTests.System.Resources {
                        // get value passing no params
                        object val = returnedNode.GetValue ((ITypeResolutionService) null);
                        Assert.IsInstanceOfType (typeof (serializable), val, "#A2");
-                       Assert.IsNotInstanceOfType (typeof (serializableSubClass), val, "#A3");
+                       AssertHelper.IsNotInstanceOfType (typeof (serializableSubClass), val, "#A3");
 
                        //get value type passing different params
                        string newType = returnedNode.GetValueTypeName (new ReturnSerializableSubClassITRS ());
index d27d4439bb680fdf7c9f9aa919c08de6694f3f3c..ffd3711a8c298212c8d3af3d1ff8feaff2235e0e 100644 (file)
@@ -50,10 +50,10 @@ namespace MonoTests.System.Resources {
 
                        object defaultVal = returnedNode.GetValue ((ITypeResolutionService) null);
                        Assert.IsInstanceOfType (typeof (serializable), defaultVal, "#A2");
-                       Assert.IsNotInstanceOfType (typeof (serializableSubClass), defaultVal, "#A3");
+                       AssertHelper.IsNotInstanceOfType (typeof (serializableSubClass), defaultVal, "#A3");
 
                        object newVal = returnedNode.GetValue (new ReturnSerializableSubClassITRS ());
-                       Assert.IsNotInstanceOfType (typeof (serializableSubClass), newVal, "#A4");
+                       AssertHelper.IsNotInstanceOfType (typeof (serializableSubClass), newVal, "#A4");
                        Assert.IsInstanceOfType (typeof (serializable), newVal, "#A5");
                }
 
@@ -88,7 +88,7 @@ namespace MonoTests.System.Resources {
 
                        // get value passing null params
                        object val = returnedNode.GetValue ((ITypeResolutionService) null);
-                       // Assert.IsNotInstanceOfType (typeof (serializable), val, "#A5"); this would fail as subclasses are id-ed as instances of parents
+                       // AssertHelper.IsNotInstanceOfType (typeof (serializable), val, "#A5"); this would fail as subclasses are id-ed as instances of parents
                        Assert.IsInstanceOfType (typeof (serializableSubClass), val, "#A4");
                }
 
index 3a6cfbda95ad293b920e005e167a955b932c697c..5c6d1a960cc56f9f898cbe9f857433d9d5ef4b9b 100644 (file)
@@ -314,7 +314,7 @@ namespace MonoTests.System.Resources {
 
                        object o = node.GetValue ((AssemblyName []) null);
 
-                       Assert.IsNotInstanceOfType (typeof (serializableSubClass), o, "#A2");
+                       AssertHelper.IsNotInstanceOfType (typeof (serializableSubClass), o, "#A2");
                        Assert.IsInstanceOfType (typeof (serializable), o, "#A3");
                        rr.Close ();
                }
index 6c69a328a088f11f3a44bdb27dd44fdc74194928..9bfe7b1b416b192272f84c49492d78bb8aa94516 100644 (file)
@@ -252,7 +252,7 @@ namespace MonoTests.System.Resources {
                        Assert.IsNotNull (finalNode, "#A3");
 
                        object finalVal = finalNode.GetValue ((ITypeResolutionService) null);
-                       Assert.IsNotInstanceOfType (typeof (serializableSubClass), finalVal, "#A4");
+                       AssertHelper.IsNotInstanceOfType (typeof (serializableSubClass), finalVal, "#A4");
                        Assert.IsInstanceOfType (typeof (serializable), finalVal, "#A5");
                }
 
index 02f4db20f28c475e67c584a36c293f3fbc5e2ac0..6514bfe1c030a91bd8928d05d494781df7933cb4 100644 (file)
@@ -91,6 +91,7 @@ namespace MonoTests.System.Windows.Forms
                }
 
                [Test]
+               [Ignore ("causes an infinite restart loop since we're not in a separate AppDomain with nunit-lite")]
                [ExpectedException (typeof (NotSupportedException))]
                public void RestartNotSupportedExceptionTest ()
                {
index acade5f6933827a5755cc1f7758ddf32ab6c3bac..18271cfba2d479509548c2ce1b963ad781bb4ca4 100644 (file)
@@ -946,10 +946,10 @@ namespace MonoTests.System.Windows.Forms
                        Assert.AreEqual (31, p.GetRowHeights ()[0], "D1");\r
                        Assert.AreEqual (31, p.GetRowHeights ()[1], "D2");\r
                        Assert.AreEqual (81, p.GetColumnWidths ()[0], "D3");\r
-                       Assert.LessOrEqual (75, p.GetColumnWidths ()[1], "D4");\r
-                       Assert.GreaterOrEqual (78, p.GetColumnWidths ()[1], "D5");\r
-                       Assert.LessOrEqual (78, p.GetColumnWidths ()[2], "D6");\r
-                       Assert.GreaterOrEqual (81, p.GetColumnWidths ()[2], "D7");\r
+                       AssertHelper.LessOrEqual (75, p.GetColumnWidths ()[1], "D4");\r
+                       AssertHelper.GreaterOrEqual (78, p.GetColumnWidths ()[1], "D5");\r
+                       AssertHelper.LessOrEqual (78, p.GetColumnWidths ()[2], "D6");\r
+                       AssertHelper.GreaterOrEqual (81, p.GetColumnWidths ()[2], "D7");\r
                }\r
                \r
                [Test]\r
@@ -1702,7 +1702,7 @@ namespace MonoTests.System.Windows.Forms
                        Assert.AreEqual (4, tlp.RowCount, "X18638-1");\r
                        Assert.AreEqual (3, tlp.ColumnCount, "X18638-2");\r
                        Assert.AreEqual (60, widths[0], "X18638-3");\r
-                       Assert.Greater (label2.Width, widths[1], "X18638-5");\r
+                       AssertHelper.Greater (label2.Width, widths[1], "X18638-5");\r
                        Assert.AreEqual (45, widths[2], "X18638-4");\r
                }\r
 \r
index 661273a3bf73358944481c32ae4ab7d58a7cc0d4..e8bdfd8829c1ef8d4662dce4a739de610503f2ac 100644 (file)
@@ -46,7 +46,7 @@ namespace MonoTests.System.XmlSerialization
                        Assert.AreEqual (string.Format(CultureInfo.InvariantCulture,
                                "{0}{0}" +
                                "/// <remarks/>{0}" +
-                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Xml\", \"{1}\")]{0}" +
+                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"nunit-lite-console\", \"0.0.0.0\")]{0}" +
                                "[System.SerializableAttribute()]{0}" +
                                "[System.Diagnostics.DebuggerStepThroughAttribute()]{0}" +
                                "[System.ComponentModel.DesignerCategoryAttribute(\"code\")]{0}" +
@@ -64,7 +64,7 @@ namespace MonoTests.System.XmlSerialization
                                "            this.namesField = value;{0}" +
                                "        }}{0}" +
                                "    }}{0}" +
-                               "}}{0}", Environment.NewLine, XmlFileVersion), sw.ToString (), "#2");
+                               "}}{0}", Environment.NewLine), sw.ToString (), "#2");
 
 
                        codeNamespace = ExportCode (typeof (ArrayClass[]));
@@ -76,7 +76,7 @@ namespace MonoTests.System.XmlSerialization
                        Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
                                "{0}{0}" +
                                "/// <remarks/>{0}" +
-                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Xml\", \"{1}\")]{0}" +
+                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"nunit-lite-console\", \"0.0.0.0\")]{0}" +
                                "[System.SerializableAttribute()]{0}" +
                                "[System.Diagnostics.DebuggerStepThroughAttribute()]{0}" +
                                "[System.ComponentModel.DesignerCategoryAttribute(\"code\")]{0}" +
@@ -93,7 +93,7 @@ namespace MonoTests.System.XmlSerialization
                                "            this.namesField = value;{0}" +
                                "        }}{0}" +
                                "    }}{0}" +
-                               "}}{0}", Environment.NewLine, XmlFileVersion), sw.ToString (), "#4");
+                               "}}{0}", Environment.NewLine), sw.ToString (), "#4");
                }
 
                [Test]
@@ -110,7 +110,7 @@ namespace MonoTests.System.XmlSerialization
                        Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
                                "{0}{0}" +
                                "/// <remarks/>{0}" +
-                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Xml\", \"{1}\")]{0}" +
+                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"nunit-lite-console\", \"0.0.0.0\")]{0}" +
                                "[System.SerializableAttribute()]{0}" +
                                "[System.Diagnostics.DebuggerStepThroughAttribute()]{0}" +
                                "[System.ComponentModel.DesignerCategoryAttribute(\"code\")]{0}" +
@@ -128,7 +128,7 @@ namespace MonoTests.System.XmlSerialization
                                "            this.itemsField = value;{0}" +
                                "        }}{0}" +
                                "    }}{0}" +
-                               "}}{0}", Environment.NewLine, XmlFileVersion), sw.ToString (), "#2");
+                               "}}{0}", Environment.NewLine), sw.ToString (), "#2");
                }
 
                [Test]
@@ -145,7 +145,7 @@ namespace MonoTests.System.XmlSerialization
                        Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
                                "{0}{0}" +
                                "/// <remarks/>{0}" +
-                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Xml\", \"{1}\")]{0}" +
+                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"nunit-lite-console\", \"0.0.0.0\")]{0}" +
                                "[System.SerializableAttribute()]{0}" +
                                "[System.Diagnostics.DebuggerStepThroughAttribute()]{0}" +
                                "[System.ComponentModel.DesignerCategoryAttribute(\"code\")]{0}" +
@@ -163,7 +163,7 @@ namespace MonoTests.System.XmlSerialization
                                "            this.cdataField = value;{0}" +
                                "        }}{0}" +
                                "    }}{0}" +
-                               "}}{0}", Environment.NewLine, XmlFileVersion), sw.ToString (), "#2");
+                               "}}{0}", Environment.NewLine), sw.ToString (), "#2");
                }
 
                [Test]
@@ -182,7 +182,7 @@ namespace MonoTests.System.XmlSerialization
                        Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
                                "{0}{0}" +
                                "/// <remarks/>{0}" +
-                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Xml\", \"{1}\")]{0}" +
+                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"nunit-lite-console\", \"0.0.0.0\")]{0}" +
                                "[System.SerializableAttribute()]{0}" +
                                "[System.Diagnostics.DebuggerStepThroughAttribute()]{0}" +
                                "[System.ComponentModel.DesignerCategoryAttribute(\"code\")]{0}" +
@@ -204,7 +204,7 @@ namespace MonoTests.System.XmlSerialization
                                "            this.myChoiceField = value;{0}" +
                                "        }}{0}" +
                                "    }}{0}" +
-                               "}}{0}", Environment.NewLine, XmlFileVersion), sw.ToString (), "#2");
+                               "}}{0}", Environment.NewLine), sw.ToString (), "#2");
                }
 
                [Test]
@@ -222,7 +222,7 @@ namespace MonoTests.System.XmlSerialization
                        Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
                                "{0}{0}" +
                                "/// <remarks/>{0}" +
-                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Xml\", \"{1}\")]{0}" +
+                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"nunit-lite-console\", \"0.0.0.0\")]{0}" +
                                "[System.SerializableAttribute()]{0}" +
                                "[System.Diagnostics.DebuggerStepThroughAttribute()]{0}" +
                                "[System.ComponentModel.DesignerCategoryAttribute(\"code\")]{0}" +
@@ -403,7 +403,7 @@ namespace MonoTests.System.XmlSerialization
                                "{0}" +
                                "/// <remarks/>{0}" +
                                "[System.FlagsAttribute()]{0}" +
-                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Xml\", \"{1}\")]{0}" +
+                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"nunit-lite-console\", \"0.0.0.0\")]{0}" +
                                "[System.SerializableAttribute()]{0}" +
                                "public enum MapModifiers {{{0}" +
                                "    {0}" +
@@ -414,7 +414,7 @@ namespace MonoTests.System.XmlSerialization
                                "    /// <remarks/>{0}" +
                                "    [System.Xml.Serialization.XmlEnumAttribute(\"protected\")]{0}" +
                                "    Protected = 2,{0}" +
-                               "}}{0}", Environment.NewLine, XmlFileVersion), sw.ToString (), "#2");
+                               "}}{0}", Environment.NewLine), sw.ToString (), "#2");
                }
 
                [Test]
@@ -431,7 +431,7 @@ namespace MonoTests.System.XmlSerialization
                        Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
                                "{0}{0}" +
                                "/// <remarks/>{0}" +
-                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Xml\", \"{1}\")]{0}" +
+                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"nunit-lite-console\", \"0.0.0.0\")]{0}" +
                                "[System.SerializableAttribute()]{0}" +
                                "[System.Xml.Serialization.XmlTypeAttribute(IncludeInSchema=false)]{0}" +
                                "[System.Xml.Serialization.XmlRootAttribute(Namespace=\"\", IsNullable=false)]{0}" +
@@ -446,7 +446,7 @@ namespace MonoTests.System.XmlSerialization
                                "    {0}" +
                                "    /// <remarks/>{0}" +
                                "    ChoiceTwo,{0}" +
-                               "}}{0}", Environment.NewLine, XmlFileVersion), sw.ToString (), "#2");
+                               "}}{0}", Environment.NewLine), sw.ToString (), "#2");
 
                        codeNamespace = ExportCode (typeof (ItemChoiceType[]));
                        Assert.IsNotNull (codeNamespace, "#3");
@@ -457,7 +457,7 @@ namespace MonoTests.System.XmlSerialization
                        Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
                                "{0}{0}" +
                                "/// <remarks/>{0}" +
-                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Xml\", \"{1}\")]{0}" +
+                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"nunit-lite-console\", \"0.0.0.0\")]{0}" +
                                "[System.SerializableAttribute()]{0}" +
                                "[System.Xml.Serialization.XmlTypeAttribute(IncludeInSchema=false)]{0}" +
                                "public enum ItemChoiceType {{{0}" +
@@ -471,7 +471,7 @@ namespace MonoTests.System.XmlSerialization
                                "    {0}" +
                                "    /// <remarks/>{0}" +
                                "    ChoiceTwo,{0}" +
-                               "}}{0}", Environment.NewLine, XmlFileVersion), sw.ToString (), "#4");
+                               "}}{0}", Environment.NewLine), sw.ToString (), "#4");
                }
 
                [Test]
@@ -488,7 +488,7 @@ namespace MonoTests.System.XmlSerialization
                        Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
                                "{0}{0}" +
                                "/// <remarks/>{0}" +
-                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Xml\", \"{1}\")]{0}" +
+                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"nunit-lite-console\", \"0.0.0.0\")]{0}" +
                                "[System.SerializableAttribute()]{0}" +
                                "[System.Diagnostics.DebuggerStepThroughAttribute()]{0}" +
                                "[System.ComponentModel.DesignerCategoryAttribute(\"code\")]{0}" +
@@ -509,7 +509,7 @@ namespace MonoTests.System.XmlSerialization
                                "}}{0}" +
                                "{0}" +
                                "/// <remarks/>{0}" +
-                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Xml\", \"{1}\")]{0}" +
+                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"nunit-lite-console\", \"0.0.0.0\")]{0}" +
                                "[System.SerializableAttribute()]{0}" +
                                "[System.Diagnostics.DebuggerStepThroughAttribute()]{0}" +
                                "[System.ComponentModel.DesignerCategoryAttribute(\"code\")]{0}" +
@@ -526,7 +526,7 @@ namespace MonoTests.System.XmlSerialization
                                "            this.somethingField = value;{0}" +
                                "        }}{0}" +
                                "    }}{0}" +
-                               "}}{0}", Environment.NewLine, XmlFileVersion), sw.ToString (), "#2");
+                               "}}{0}", Environment.NewLine), sw.ToString (), "#2");
                }
 
                [Test]
@@ -544,7 +544,7 @@ namespace MonoTests.System.XmlSerialization
                        Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
                                "{0}{0}" +
                                "/// <remarks/>{0}" +
-                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Xml\", \"{1}\")]{0}" +
+                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"nunit-lite-console\", \"0.0.0.0\")]{0}" +
                                "[System.SerializableAttribute()]{0}" +
                                "[System.Diagnostics.DebuggerStepThroughAttribute()]{0}" +
                                "[System.ComponentModel.DesignerCategoryAttribute(\"code\")]{0}" +
@@ -578,7 +578,7 @@ namespace MonoTests.System.XmlSerialization
                                "}}{0}" +
                                "{0}" +
                                "/// <remarks/>{0}" +
-                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Xml\", \"{1}\")]{0}" +
+                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"nunit-lite-console\", \"0.0.0.0\")]{0}" +
                                "[System.SerializableAttribute()]{0}" +
                                "[System.Diagnostics.DebuggerStepThroughAttribute()]{0}" +
                                "[System.ComponentModel.DesignerCategoryAttribute(\"code\")]{0}" +
@@ -667,7 +667,7 @@ namespace MonoTests.System.XmlSerialization
                                "{0}" +
                                "/// <remarks/>{0}" +
                                "[System.FlagsAttribute()]{0}" +
-                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Xml\", \"{1}\")]{0}" +
+                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"nunit-lite-console\", \"0.0.0.0\")]{0}" +
                                "[System.SerializableAttribute()]{0}" +
                                "[System.Xml.Serialization.XmlTypeAttribute(Namespace=\"some:urn\")]{0}" +
                                "public enum FlagEnum {{{0}" +
@@ -786,7 +786,7 @@ namespace MonoTests.System.XmlSerialization
                                "{0}" +
                                "/// <remarks/>{0}" +
                                "[System.FlagsAttribute()]{0}" +
-                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Xml\", \"{1}\")]{0}" +
+                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"nunit-lite-console\", \"0.0.0.0\")]{0}" +
                                "[System.SerializableAttribute()]{0}" +
                                "[System.Xml.Serialization.XmlTypeAttribute(Namespace=\"urn:myNS\")]{0}" +
                                "public enum FlagEnum {{{0}" +
@@ -806,7 +806,7 @@ namespace MonoTests.System.XmlSerialization
                                "{0}" +
                                "/// <remarks/>{0}" +
                                "[System.FlagsAttribute()]{0}" +
-                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Xml\", \"{1}\")]{0}" +
+                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"nunit-lite-console\", \"0.0.0.0\")]{0}" +
                                "[System.SerializableAttribute()]{0}" +
                                "[System.Xml.Serialization.XmlTypeAttribute(Namespace=\"urn:myNS\")]{0}" +
                                "public enum FlagEnum_Encoded {{{0}" +
@@ -819,7 +819,7 @@ namespace MonoTests.System.XmlSerialization
                                "    {0}" +
                                "    /// <remarks/>{0}" +
                                "    e4 = 4,{0}" +
-                               "}}{0}", Environment.NewLine, XmlFileVersion), sw.ToString (), "#2");
+                               "}}{0}", Environment.NewLine), sw.ToString (), "#2");
                }
 
                [Test]
@@ -836,7 +836,7 @@ namespace MonoTests.System.XmlSerialization
                        Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
                                "{0}{0}" +
                                "/// <remarks/>{0}" +
-                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Xml\", \"{1}\")]{0}" +
+                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"nunit-lite-console\", \"0.0.0.0\")]{0}" +
                                "[System.SerializableAttribute()]{0}" +
                                "[System.Diagnostics.DebuggerStepThroughAttribute()]{0}" +
                                "[System.ComponentModel.DesignerCategoryAttribute(\"code\")]{0}" +
@@ -855,7 +855,7 @@ namespace MonoTests.System.XmlSerialization
                                "            this.somethingField = value;{0}" +
                                "        }}{0}" +
                                "    }}{0}" +
-                               "}}{0}", Environment.NewLine, XmlFileVersion), sw.ToString (), "#2");
+                               "}}{0}", Environment.NewLine), sw.ToString (), "#2");
                }
 
                [Test]
@@ -909,7 +909,7 @@ namespace MonoTests.System.XmlSerialization
                                "{0}{0}" +
                                "/// <remarks/>{0}" +
                                "[System.FlagsAttribute()]{0}" +
-                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Xml\", \"{1}\")]{0}" +
+                               "[System.CodeDom.Compiler.GeneratedCodeAttribute(\"nunit-lite-console\", \"0.0.0.0\")]{0}" +
                                "[System.SerializableAttribute()]{0}" +
                                "[System.Xml.Serialization.XmlRootAttribute(Namespace=\"\", IsNullable=false)]{0}" +
                                "public enum ZeroFlagEnum {{{0}" +
@@ -925,7 +925,7 @@ namespace MonoTests.System.XmlSerialization
                                "    /// <remarks/>{0}" +
                                "    [System.Xml.Serialization.XmlEnumAttribute(\"tns:t<w>o\")]{0}" +
                                "    e2 = 4,{0}" +
-                               "}}{0}", Environment.NewLine, XmlFileVersion), sw.ToString (), "#2");
+                               "}}{0}", Environment.NewLine), sw.ToString (), "#2");
                }
 
                [Test]
@@ -1005,15 +1005,6 @@ namespace MonoTests.System.XmlSerialization
                        return codeNamespace;
                }
 
-               string XmlFileVersion {
-                       get {
-                               Assembly xmlAsm = typeof (XmlDocument).Assembly;
-                               AssemblyFileVersionAttribute afv = (AssemblyFileVersionAttribute)
-                                       Attribute.GetCustomAttribute (xmlAsm, typeof (AssemblyFileVersionAttribute));
-                               return afv.Version;
-                       }
-               }
-
                [XmlRootAttribute ("root", Namespace="urn:aNS", IsNullable=false)]
                public class Root
                {
index 493bc6a8ad04504160745edfb05ef59ca5cc06d9..2624f2a5ba087f3629c397f41d376b6fd072317d 100644 (file)
@@ -136,7 +136,7 @@ namespace MonoTests.System.Xml
                        Assert.AreEqual ("file", resolved.Scheme);
                        var task = sr.GetEntityAsync (resolved, null, typeof (Stream));
                        Assert.That (task.Wait (3000));
-                       Assert.IsInstanceOfType (typeof (Stream), task.Result);
+                       Assert.IsInstanceOfType (typeof (FileStream), task.Result);
                }
 
        }
index 693d4a2e296436b7c6c4cc7a24c97a727acd6c46..67efb6025e6504d6830210c54bb1fa53b28dbe70 100644 (file)
@@ -1,3 +1,4 @@
+../../test-helpers/NunitHelpers.cs
 System.Xml.Linq/ExtensionsTest.cs
 System.Xml.Linq/XAttributeTest.cs
 System.Xml.Linq/XCommentTest.cs
index da577e644effc0f851c9617fa46466d4140a3c4a..bbbf42e13f5d5a1b9374221ec8f40308bd423432 100644 (file)
@@ -220,8 +220,8 @@ namespace MonoTests.System.Xml.Schema
                                }
                        }
 
-                       Assert.GreaterOrEqual (afterNoOfAttributes, beforeNoOfAttributes, "newAttributes");
-                       Assert.GreaterOrEqual (afterNoOfElements, beforeNoOfElements, "newElements");       
+                       AssertHelper.GreaterOrEqual (afterNoOfAttributes, beforeNoOfAttributes, "newAttributes");
+                       AssertHelper.GreaterOrEqual (afterNoOfElements, beforeNoOfElements, "newElements");       
                }
 
                /*
index b4f825fb50207e186faa7c8f71352286b2c8c4ca..3c4d4dfc432545695f408db248194988c893da40 100644 (file)
@@ -34,6 +34,8 @@ endif
 TEST_MCS_FLAGS = -nowarn:618,672,219,67,169,612 \
        $(foreach f, $(TEST_RESOURCES), -resource:$(f),$(notdir $(f)))
 
+TEST_NUNITLITE_APP_CONFIG_GLOBAL=Test/test-config-file
+
 REFERENCE_SOURCES_FLAGS = -d:FEATURE_PAL,SYSTEM_NAMESPACE,MONO,PLATFORM_UNIX
 ifndef NO_PROCESS_START
 REFERENCE_SOURCES_FLAGS += -d:MONO_FEATURE_PROCESS_START
@@ -101,7 +103,6 @@ endif
 
 EXTRA_DISTFILES = \
        Test/test-config-file                           \
-       Test/test-config-file-net-2.0                   \
        Test/System.Security.Cryptography.X509Certificates/pkits/Makefile       \
        Test/System.Security.Cryptography.X509Certificates/pkits/README         \
        Test/System.Security.Cryptography.X509Certificates/pkits/x509build.cs   \
@@ -157,10 +158,7 @@ $(the_libdir_base)System.Configuration.dll:
 
 $(build_lib): $(CYCLIC_DEP_FILES)
 
-$(test_lib): $(test_lib).config $(TEST_RESOURCES)
-
-$(test_lib).config: Test/test-config-file
-       cp $< $@
+$(test_lib): $(TEST_RESOURCES)
 
 CLEAN_FILES = $(test_lib).config $(bare_libdir)/System.dll $(secxml_libdir)/System.dll $(bare_libdir)/System.dll.mdb $(secxml_libdir)/System.dll.mdb
 
index b2e863b085a0366ac5b43f8324aa8c41a919fba2..8a6bf30903dc24d7120aaa236f9afcf22ca11fb7 100644 (file)
@@ -64,10 +64,6 @@ namespace Mono.Btls
                [DllImport (BTLS_DYLIB)]
                extern static int mono_btls_x509_lookup_add_mono (IntPtr handle, IntPtr monoLookup);
 
-               [DllImport (BTLS_DYLIB)]
-               extern static void mono_btls_x509_lookup_method_mono_init (
-                       IntPtr handle, IntPtr instance, IntPtr by_subject_func);
-
                [DllImport (BTLS_DYLIB)]
                extern static int mono_btls_x509_lookup_init (IntPtr handle);
 
diff --git a/mcs/class/System/Mono.Btls/MonoBtlsX509NameList.cs b/mcs/class/System/Mono.Btls/MonoBtlsX509NameList.cs
deleted file mode 100644 (file)
index 005ffd0..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-//
-// MonoBtlsX509NameList.cs
-//
-// Author:
-//       Martin Baulig <martin.baulig@xamarin.com>
-//
-// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-#if SECURITY_DEP && MONO_FEATURE_BTLS
-using System;
-using System.IO;
-using System.Text;
-using System.Runtime.InteropServices;
-using System.Runtime.CompilerServices;
-
-namespace Mono.Btls
-{
-       class MonoBtlsX509NameList : MonoBtlsObject
-       {
-               internal class BoringX509NameListHandle : MonoBtlsHandle
-               {
-                       bool dontFree;
-
-                       internal BoringX509NameListHandle (IntPtr handle, bool ownsHandle)
-                               : base (handle, ownsHandle)
-                       {
-                               this.dontFree = !ownsHandle;
-                       }
-
-                       protected override bool ReleaseHandle ()
-                       {
-                               if (!dontFree)
-                                       mono_btls_x509_name_list_free (handle);
-                               return true;
-                       }
-               }
-
-               [DllImport (BTLS_DYLIB)]
-               extern static IntPtr mono_btls_x509_name_list_new ();
-
-               [DllImport (BTLS_DYLIB)]
-               extern static int mono_btls_x509_name_list_get_count (IntPtr handle);
-
-               [DllImport (BTLS_DYLIB)]
-               extern static int mono_btls_x509_name_list_add (IntPtr handle, IntPtr name);
-
-               [DllImport (BTLS_DYLIB)]
-               extern static IntPtr mono_btls_x509_name_list_get_item (IntPtr handle, int index);
-
-               [DllImport (BTLS_DYLIB)]
-               extern static void mono_btls_x509_name_list_free (IntPtr handle);
-
-               new internal BoringX509NameListHandle Handle {
-                       get { return (BoringX509NameListHandle)base.Handle; }
-               }
-
-               internal MonoBtlsX509NameList (BoringX509NameListHandle handle)
-                       : base (handle)
-               {
-               }
-
-               internal MonoBtlsX509NameList ()
-                       : this (Create_internal ())
-               {
-               }
-
-               static BoringX509NameListHandle Create_internal ()
-               {
-                       var handle = mono_btls_x509_name_list_new ();
-                       if (handle == IntPtr.Zero)
-                               throw new MonoBtlsException ();
-                       return new BoringX509NameListHandle (handle, true);
-               }
-
-               public int GetCount ()
-               {
-                       CheckThrow ();
-                       return mono_btls_x509_name_list_get_count (
-                               Handle.DangerousGetHandle ());
-               }
-
-               public MonoBtlsX509Name GetItem (int index)
-               {
-                       CheckThrow ();
-                       if (index < 0 || index >= GetCount ())
-                               throw new ArgumentOutOfRangeException ();
-                       var ptr = mono_btls_x509_name_list_get_item (
-                               Handle.DangerousGetHandle (), index);
-                       if (ptr == IntPtr.Zero)
-                               return null;
-                       return new MonoBtlsX509Name (
-                               new MonoBtlsX509Name.BoringX509NameHandle (ptr, true));
-               }
-
-               public void Add (MonoBtlsX509Name name)
-               {
-                       CheckThrow ();
-                       mono_btls_x509_name_list_add (
-                               Handle.DangerousGetHandle (),
-                               name.Handle.DangerousGetHandle ());
-               }
-       }
-}
-#endif
index db2e81529ba7704cdfee952f59b1284cb07ac1ac..f9bd47396e6328a2a272c22832a6dcb873b16423 100644 (file)
@@ -2,7 +2,9 @@
 #if SECURITY_DEP
 using System;
 using MSI = Mono.Security.Interface;
+#if MONO_FEATURE_BTLS
 using Mono.Btls;
+#endif
 
 namespace Mono.Net.Security
 {
@@ -17,10 +19,12 @@ namespace Mono.Net.Security
                        case "default":
                        case "legacy":
                                return new LegacyTlsProvider ();
+#if MONO_FEATURE_BTLS
                        case "btls":
                                if (!IsBtlsSupported ())
                                        throw new NotSupportedException ("BTLS in not supported!");
                                return new MonoBtlsProvider ();
+#endif
                        default:
                                throw new NotSupportedException (string.Format ("Invalid TLS Provider: `{0}'.", provider));
                        }
index b7f3043a5941e184860fa86382ff491aed9709e0..8d92f001d56d241281f3bd1f1be02508be82bf4b 100644 (file)
@@ -2,7 +2,7 @@ using System.Collections;
 
 namespace System.Net
 {
-       static class UnsafeNclNativeMethods
+       static partial class UnsafeNclNativeMethods
        {
                internal static unsafe class HttpApi 
                {
diff --git a/mcs/class/System/ReferenceSources/SecureStringHelper.cs b/mcs/class/System/ReferenceSources/SecureStringHelper.cs
new file mode 100644 (file)
index 0000000..31372e2
--- /dev/null
@@ -0,0 +1,47 @@
+using System.Security;
+using System.Runtime.InteropServices;
+
+namespace System.Net
+{
+       static partial class UnsafeNclNativeMethods
+       {
+        internal unsafe static class SecureStringHelper
+        {
+            internal static string CreateString(SecureString secureString)
+            {
+                string plainString;
+                IntPtr bstr = IntPtr.Zero;
+
+                if (secureString == null || secureString.Length == 0)
+                    return String.Empty;
+
+                try
+                {
+                    bstr = Marshal.SecureStringToBSTR(secureString);
+                    plainString = Marshal.PtrToStringBSTR(bstr);
+                }
+                finally
+                {
+                    if (bstr != IntPtr.Zero)
+                        Marshal.ZeroFreeBSTR(bstr);
+                }
+                return plainString;
+            }
+
+            internal static SecureString CreateSecureString(string plainString)
+            {
+                SecureString secureString;
+
+                if (plainString == null || plainString.Length == 0)
+                    return new SecureString();
+
+                fixed (char* pch = plainString)
+                {
+                    secureString = new SecureString(pch, plainString.Length);
+                }
+
+                return secureString;
+            }
+        }
+    }
+}
\ No newline at end of file
index 5979582c21dd72e6e5aa7e2eb199650288ae54ea..6d6ee2b5d237c077793bed3840d6984f672da2d3 100644 (file)
     <Compile Include="..\referencesource\System\net\System\Net\mail\TransferEncoding.cs" />\r
     <Compile Include="..\referencesource\System\net\System\Net\mail\WriteStateInfoBase.cs" />\r
     <Compile Include="..\referencesource\System\net\System\Net\NetworkAccess.cs" />\r
+    <Compile Include="..\referencesource\System\net\System\Net\NetworkCredential.cs" />\r
     <Compile Include="..\referencesource\System\net\System\Net\NetworkInformation\DuplicateAddressDetectionState.cs" />\r
     <Compile Include="..\referencesource\System\net\System\Net\NetworkInformation\GatewayIPAddressInformation.cs" />\r
     <Compile Include="..\referencesource\System\net\System\Net\NetworkInformation\GatewayIPAddressInformationCollection.cs" />\r
     <Compile Include="Mono.Btls\MonoBtlsX509LookupType.cs" />\r
     <Compile Include="Mono.Btls\MonoBtlsX509Name.cs" />\r
     <Compile Include="Mono.Btls\MonoBtlsX509NameEntryType.cs" />\r
-    <Compile Include="Mono.Btls\MonoBtlsX509NameList.cs" />\r
     <Compile Include="Mono.Btls\MonoBtlsX509Purpose.cs" />\r
     <Compile Include="Mono.Btls\MonoBtlsX509Revoked.cs" />\r
     <Compile Include="Mono.Btls\MonoBtlsX509Store.cs" />\r
     <Compile Include="ReferenceSources\Logging.cs" />\r
     <Compile Include="ReferenceSources\NativeMethods.cs" />\r
     <Compile Include="ReferenceSources\RequestCacheProtocol.cs" />\r
+    <Compile Include="ReferenceSources\SecureStringHelper.cs" />\r
     <Compile Include="ReferenceSources\SettingsSectionInternal.cs" />\r
     <Compile Include="ReferenceSources\Socket.cs" />\r
     <Compile Include="ReferenceSources\SR.cs" />\r
     <Compile Include="System.Net\MacProxy.cs" />\r
     <Compile Include="System.Net\MonoHttpDate.cs" />\r
     <Compile Include="System.Net\NetConfig.cs" />\r
-    <Compile Include="System.Net\NetworkCredential.cs" />\r
     <Compile Include="System.Net\NtlmClient.cs" />\r
     <Compile Include="System.Net\RequestStream.cs" />\r
     <Compile Include="System.Net\ResponseStream.cs" />\r
index fa55d4fa95ccb1bb542fe4ee4d39c3c256493a99..8e045c3da847c7730f5d0d35115d7d9f09e20388 100644 (file)
     <Compile Include="..\referencesource\System\net\System\Net\mail\TransferEncoding.cs" />\r
     <Compile Include="..\referencesource\System\net\System\Net\mail\WriteStateInfoBase.cs" />\r
     <Compile Include="..\referencesource\System\net\System\Net\NetworkAccess.cs" />\r
+    <Compile Include="..\referencesource\System\net\System\Net\NetworkCredential.cs" />\r
     <Compile Include="..\referencesource\System\net\System\Net\NetworkInformation\DuplicateAddressDetectionState.cs" />\r
     <Compile Include="..\referencesource\System\net\System\Net\NetworkInformation\GatewayIPAddressInformation.cs" />\r
     <Compile Include="..\referencesource\System\net\System\Net\NetworkInformation\GatewayIPAddressInformationCollection.cs" />\r
     <Compile Include="Mono.Btls\MonoBtlsX509LookupType.cs" />\r
     <Compile Include="Mono.Btls\MonoBtlsX509Name.cs" />\r
     <Compile Include="Mono.Btls\MonoBtlsX509NameEntryType.cs" />\r
-    <Compile Include="Mono.Btls\MonoBtlsX509NameList.cs" />\r
     <Compile Include="Mono.Btls\MonoBtlsX509Purpose.cs" />\r
     <Compile Include="Mono.Btls\MonoBtlsX509Revoked.cs" />\r
     <Compile Include="Mono.Btls\MonoBtlsX509Store.cs" />\r
     <Compile Include="ReferenceSources\Logging.cs" />\r
     <Compile Include="ReferenceSources\NativeMethods.cs" />\r
     <Compile Include="ReferenceSources\RequestCacheProtocol.cs" />\r
+    <Compile Include="ReferenceSources\SecureStringHelper.cs" />\r
     <Compile Include="ReferenceSources\SettingsSectionInternal.cs" />\r
     <Compile Include="ReferenceSources\Socket.cs" />\r
     <Compile Include="ReferenceSources\SR.cs" />\r
     <Compile Include="System.Net\MacProxy.cs" />\r
     <Compile Include="System.Net\MonoHttpDate.cs" />\r
     <Compile Include="System.Net\NetConfig.cs" />\r
-    <Compile Include="System.Net\NetworkCredential.cs" />\r
     <Compile Include="System.Net\NtlmClient.cs" />\r
     <Compile Include="System.Net\RequestStream.cs" />\r
     <Compile Include="System.Net\ResponseStream.cs" />\r
index fbb01b231b47026b59547d5b6b86734334446060..1f644f32d70ddb234dd5dfc55aee7dd6682f31cc 100644 (file)
     <Compile Include="..\referencesource\System\net\System\Net\mail\TransferEncoding.cs" />\r
     <Compile Include="..\referencesource\System\net\System\Net\mail\WriteStateInfoBase.cs" />\r
     <Compile Include="..\referencesource\System\net\System\Net\NetworkAccess.cs" />\r
+    <Compile Include="..\referencesource\System\net\System\Net\NetworkCredential.cs" />\r
     <Compile Include="..\referencesource\System\net\System\Net\NetworkInformation\DuplicateAddressDetectionState.cs" />\r
     <Compile Include="..\referencesource\System\net\System\Net\NetworkInformation\GatewayIPAddressInformation.cs" />\r
     <Compile Include="..\referencesource\System\net\System\Net\NetworkInformation\GatewayIPAddressInformationCollection.cs" />\r
     <Compile Include="Mono.Btls\MonoBtlsX509LookupType.cs" />\r
     <Compile Include="Mono.Btls\MonoBtlsX509Name.cs" />\r
     <Compile Include="Mono.Btls\MonoBtlsX509NameEntryType.cs" />\r
-    <Compile Include="Mono.Btls\MonoBtlsX509NameList.cs" />\r
     <Compile Include="Mono.Btls\MonoBtlsX509Purpose.cs" />\r
     <Compile Include="Mono.Btls\MonoBtlsX509Revoked.cs" />\r
     <Compile Include="Mono.Btls\MonoBtlsX509Store.cs" />\r
     <Compile Include="ReferenceSources\Logging.cs" />\r
     <Compile Include="ReferenceSources\NativeMethods.cs" />\r
     <Compile Include="ReferenceSources\RequestCacheProtocol.cs" />\r
+    <Compile Include="ReferenceSources\SecureStringHelper.cs" />\r
     <Compile Include="ReferenceSources\SettingsSectionInternal.cs" />\r
     <Compile Include="ReferenceSources\Socket.cs" />\r
     <Compile Include="ReferenceSources\SR.cs" />\r
     <Compile Include="System.Net\MacProxy.cs" />\r
     <Compile Include="System.Net\MonoHttpDate.cs" />\r
     <Compile Include="System.Net\NetConfig.cs" />\r
-    <Compile Include="System.Net\NetworkCredential.cs" />\r
     <Compile Include="System.Net\NtlmClient.cs" />\r
     <Compile Include="System.Net\RequestStream.cs" />\r
     <Compile Include="System.Net\ResponseStream.cs" />\r
index 08c2630eaccea76530243ebdab360af8c5b468ce..752dcd08d8b5621fe15229aa4f13617c83bb2ea9 100644 (file)
@@ -2453,9 +2453,6 @@ m_Handle, buffer, offset + sent, size - sent, socketFlags, out nativeError, is_b
                {
                        ThrowIfDisposedAndClosed ();
 
-                       if (optionLevel == SocketOptionLevel.Socket && optionName == SocketOptionName.ReuseAddress && optionValue != 0 && !SupportsPortReuse (protocolType))
-                               throw new SocketException ((int) SocketError.OperationNotSupported, "Operating system sockets do not support ReuseAddress.\nIf your socket is not intended to bind to the same address and port multiple times remove this option, otherwise you should ignore this exception inside a try catch and check that ReuseAddress is true before binding to the same address and port multiple times.");
-
                        int error;
                        SetSocketOption_internal (m_Handle, optionLevel, optionName, null, null, optionValue, out error);
 
diff --git a/mcs/class/System/System.Net/NetworkCredential.cs b/mcs/class/System/System.Net/NetworkCredential.cs
deleted file mode 100644 (file)
index faba55d..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-//
-// System.Net.NetworkCredential.cs
-//
-// Authors: Duncan Mak (duncan@ximian.com)
-//          Rolf Bjarne KVinge (rolf@xamarin.com)
-//          Marek Safar (marek.safar@gmail.com)
-//
-// (C) Ximian, Inc.
-// Copyright (C) 2010 Novell, Inc (http://www.novell.com)
-// Copyright (C) 2011, 2014 Xamarin Inc (http://www.xamarin.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System.Security;
-
-namespace System.Net
-{
-       public class NetworkCredential : ICredentials
-                                       , ICredentialsByHost
-       {
-               // Fields
-               string userName;
-               string password;
-               string domain;
-               
-               SecureString securePassword;
-
-               // Constructors
-               public NetworkCredential ()
-               {
-               }
-
-               public NetworkCredential (string userName, string password)
-               {
-                       this.userName = userName;
-                       this.password = password;
-               }
-
-               public NetworkCredential (string userName, string password, string domain)
-                       : this (userName, password)
-               {
-                       this.domain = domain;
-               }
-
-               public NetworkCredential (string userName, SecureString password)
-               {
-                       this.userName = userName;
-                       SecurePassword = password;
-               }
-
-               public NetworkCredential (string userName, SecureString password, string domain)
-                       : this (userName, password)
-               {
-                       this.domain = domain;
-               }
-               // Properties
-
-               public string Domain {
-                       get { return domain ?? String.Empty; }
-                       set { domain = value; }
-               }
-
-               public string UserName {
-                       get { return userName ?? String.Empty; }
-                       set { userName = value; }                       
-               }
-
-               public string Password {
-                       get { return password ?? String.Empty; }
-                       set { password = value; }
-               }
-
-               public SecureString SecurePassword {
-                       get { return securePassword; }
-                       set {
-                               if (value == null) {
-                                       securePassword = new SecureString ();
-                               } else {
-                                       securePassword = value;
-                               }
-                       }
-               }
-
-               public NetworkCredential GetCredential (Uri uri, string authType)
-               {
-                       return this;
-               }
-
-               public NetworkCredential GetCredential (string host, int port, string authenticationType)
-               {
-                       return this;
-               }
-       }
-}
index e1cabcf69ae5cddbf98a5542667b8eba0b381f83..d404a646402a9b9cc3738de38e4b90cc26c518c8 100644 (file)
@@ -337,7 +337,6 @@ System.Net.Mail/SmtpStatusCode.cs
 System.Net/MacProxy.cs
 System.Net/MonoHttpDate.cs
 System.Net/NetConfig.cs
-System.Net/NetworkCredential.cs
 System.Net.NetworkInformation/IcmpV4Statistics.cs
 System.Net.NetworkInformation/IcmpV6Statistics.cs
 System.Net.NetworkInformation/IPAddressCollection.cs
@@ -541,7 +540,6 @@ Mono.Btls/MonoBtlsX509LookupMonoCollection.cs
 Mono.Btls/MonoBtlsX509LookupMono.cs
 Mono.Btls/MonoBtlsX509LookupType.cs
 Mono.Btls/MonoBtlsX509Name.cs
-Mono.Btls/MonoBtlsX509NameList.cs
 Mono.Btls/MonoBtlsX509NameEntryType.cs
 Mono.Btls/MonoBtlsX509Purpose.cs
 Mono.Btls/MonoBtlsX509Revoked.cs
@@ -585,6 +583,7 @@ ReferenceSources/Logging.cs
 ReferenceSources/NativeMethods.cs
 ReferenceSources/RequestCacheProtocol.cs
 ReferenceSources/SettingsSectionInternal.cs
+ReferenceSources/SecureStringHelper.cs
 ReferenceSources/Socket.cs
 ReferenceSources/SR.cs
 ReferenceSources/SR2.cs
@@ -1024,6 +1023,7 @@ ReferenceSources/Win32Exception.cs
 ../referencesource/System/net/System/Net/IWebProxyFinder.cs
 ../referencesource/System/net/System/Net/IWebRequestCreate.cs
 ../referencesource/System/net/System/Net/NetworkAccess.cs
+../referencesource/System/net/System/Net/NetworkCredential.cs
 ../referencesource/System/net/System/Net/ProtocolViolationException.cs
 ../referencesource/System/net/System/Net/TransportContext.cs
 ../referencesource/System/net/System/Net/TransportType.cs
index 5d59fa64718a600b4d0cb4d16a0a3ae9a3893ad0..dc4f4aaa54ec0200a97c579834cc1af691bc7012 100644 (file)
@@ -33,8 +33,10 @@ using System.Net.Security;
 using System.Security.Cryptography.X509Certificates;
 #if SECURITY_DEP
 using MSX = Mono.Security.X509;
+#if MONO_FEATURE_BTLS
 using Mono.Btls;
 #endif
+#endif
 
 namespace System {
 
@@ -60,12 +62,14 @@ namespace System {
                                                        "TrustEvaluateSsl",
                                                        ignoreCase:false,
                                                        throwOnBindFailure:true);
+#if MONO_FEATURE_BTLS
                        certStoreLookup = (Func<long, bool, byte[]>)
                                Delegate.CreateDelegate (typeof (Func<long, bool, byte[]>),
                                                        t,
                                                        "CertStoreLookup",
                                                        ignoreCase:false,
                                                        throwOnBindFailure:true);
+#endif  // MONO_FEATURE_BTLS
 #endif  // SECURITY_DEP
                        getDefaultProxy = (Func<IWebProxy>)Delegate.CreateDelegate (
                                typeof (Func<IWebProxy>), t, "GetDefaultProxy",
@@ -92,6 +96,7 @@ namespace System {
                        return trustEvaluateSsl (certsRawData);
                }
 
+#if MONO_FEATURE_BTLS
                internal static MonoBtlsX509 CertStoreLookup (MonoBtlsX509Name name)
                {
                        var hash = name.GetHash ();
@@ -109,6 +114,7 @@ namespace System {
 
                        return MonoBtlsX509.LoadFromData (result, MonoBtlsX509Format.DER);
                }
+#endif  // MONO_FEATURE_BTLS
 #endif  // SECURITY_DEP
 
                internal static IWebProxy GetDefaultProxy ()
index 6ec32758faf518b7194ff3462876a81e2fc0610b..24351699070af87a50754ae78540b810f07e5f66 100644 (file)
@@ -1,3 +1,4 @@
+../../test-helpers/NunitHelpers.cs
 Microsoft.CSharp/CodeGeneratorFromCompileUnitTest.cs
 Microsoft.CSharp/CodeGeneratorFromExpressionTest.cs
 Microsoft.CSharp/CodeGeneratorFromNamespaceTest.cs
index c6ccdf0a26ab1e81b475f0a646aaf63296196b3e..823204cf4867366cebc2cd86bffcdeb601dfa29c 100644 (file)
@@ -53,7 +53,7 @@ namespace MonoTests.System.CodeDom.Compiler
                        int importPosition = result.IndexOf (IMPORT);
                        int attributePosition = result.IndexOf (ATTRIBUTE);
 
-                       Assert.Greater (attributePosition, importPosition, "Actual order: " + result);
+                       AssertHelper.Greater (attributePosition, importPosition, "Actual order: " + result);
                }
 
                [Test]
index b6baac08e8546b092a48cb849ec3fc9debb3a37b..6586c4c092f9c554eae94a7f1bb7a62ba03bb79c 100644 (file)
@@ -38,9 +38,6 @@ using System.Text;
 using System.Runtime.Serialization;
 using System.Runtime.Serialization.Formatters.Binary;
 using NUnit.Framework;
-#if !MOBILE
-using NUnit.Framework.SyntaxHelpers;
-#endif
 
 namespace MonoTests.System.Collections.Generic
 {
index 820e84d2a89326a2ffe8a5de07f2403b4f0e7d37..07195bb9246a85a71c758c528406365828b7e7f8 100644 (file)
@@ -53,7 +53,7 @@ namespace MonoTests.System.Diagnostics
                public void ConstructorNullName ()
                {
                        SourceSwitch s = new SourceSwitch (null);
-                       Assert.IsEmpty (s.DisplayName);
+                       AssertHelper.IsEmpty (s.DisplayName);
                }
 
                [Test]
index 9d97fc8b53c615a8589e7fbea1a8cdc0d030038e..d8821a00c2ddbb42d380e3c49437300be24eac11 100644 (file)
@@ -190,8 +190,8 @@ namespace MonoTests.System.Diagnostics {
                public void NullSwitchHasEmptyDisplayNameAndDescription ()
                {
                        var s = new TestNullSwitch ();
-                       Assert.IsEmpty (s.DisplayName);
-                       Assert.IsEmpty (s.Description);
+                       AssertHelper.IsEmpty (s.DisplayName);
+                       AssertHelper.IsEmpty (s.Description);
                }
        }
 }
index 0fe01aaf102cd2c04b499ef4f1822e4da01a6955..1aa78a9d99368a75faa4bee76c1c0eecb03e35f8 100644 (file)
@@ -410,6 +410,46 @@ namespace MonoTests.System.IO.Compression
                        using (var unZippedStream = new StreamReader (gZipStream, Encoding.UTF8)) {
                                unZipped = unZippedStream.ReadToEnd ();
                        }
+
+                       Assert.AreEqual(1877, unZipped.Length);
+               }
+
+               [Test]
+               public void Bug44994_Inflate()
+               {
+                       var base64String = @"7cWxCQAgDACwpeBjgqsgXiHU0fd9QzBLErX1EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADepcxcuU/atm3btm3btm3btm3btm3btm3btm3btm3btm3btm3btm3btm3btm3btm3btm3btm3btm3btm3btm3btm3btm3btm3btm3btm3btm3btm3btm3btm3btm3btm37zy8=";
+
+                       byte[] byteArray = Convert.FromBase64String(base64String);
+                       string unZipped = null;
+
+                       using (var zippedMemoryStream = new MemoryStream(byteArray))
+                       using (var gZipStream = new DeflateStream(zippedMemoryStream, CompressionMode.Decompress))
+                       using (var unzippedMemStream = new MemoryStream())
+                       using (var unZippedStream = new StreamReader(gZipStream, Encoding.UTF8))
+                       {
+                               unZipped = unZippedStream.ReadToEnd();
+                       }
+
+                       Assert.AreEqual(81942, unZipped.Length);
+               }
+
+               [Test]
+               [Category ("MobileNotWorking")]
+               public void Bug44994_InflateByteByByte()
+               {
+                       int byteCount = 0;
+                       using (var fileStream = File.OpenRead(Path.Combine("Test", "compressed.bin")))
+                       {
+                               using (var deflateStream = new DeflateStream(fileStream, CompressionMode.Decompress, false))
+                               {
+                                       while (deflateStream.ReadByte() != -1)
+                                       {
+                                               byteCount++;
+                                       }
+                               }
+                       }
+
+                       Assert.AreEqual(125387, byteCount);
                }
        }
 }
index dbe3255cd6893121155b8f82242724cb8090805f..e5c46f8f901638ac860e8c8824a69e9327f8253e 100644 (file)
@@ -28,6 +28,7 @@
 
 using System;
 using System.Net;
+using System.Security;
 
 using NUnit.Framework;
 
@@ -99,6 +100,21 @@ namespace MonoTests.System.Net {
                        nc = new NetworkCredential ("user", "********", "dom");
                        CheckCustom (nc);
                }
+
+               [Test]
+               public void DecipherSecureString ()
+               {
+                       // many code snippets suggest using the following to get the decrypted string from a SecureString
+                       var ss = new SecureString ();
+                       ss.AppendChar('h');
+                       ss.AppendChar('e');
+                       ss.AppendChar('l');
+                       ss.AppendChar('l');
+                       ss.AppendChar('o');
+                       string plain = new NetworkCredential (string.Empty, ss).Password;
+                       Assert.AreEqual ("hello", plain);
+               }
        }
 }
 
index 5da8a5d59c78e11bb00c93fe1c1041235e7a9efb..5f6daa28b60f1eadacf6cea0aaf73bc77ebe5cfa 100644 (file)
@@ -37,6 +37,7 @@ using System.IO;
 using System.Security.Cryptography;
 using System.Security.Cryptography.X509Certificates;
 using System.Text;
+using System.Reflection;
 
 namespace MonoTests.System.Security.Cryptography.X509Certificates {
 
@@ -64,7 +65,7 @@ namespace MonoTests.System.Security.Cryptography.X509Certificates {
                public void FixtureSetUp ()
                {
                        base_dir = String.Format ("{0}{1}Test{1}System.Security.Cryptography.X509Certificates{1}pkits{1}certs",
-                               Directory.GetCurrentDirectory (), Path.DirectorySeparatorChar);
+                               Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location), Path.DirectorySeparatorChar);
                        if (!Directory.Exists (base_dir))
                                Assert.Ignore ("PKITS tests data not found under '{0}'.", new object[] { base_dir });
 
@@ -75,7 +76,8 @@ namespace MonoTests.System.Security.Cryptography.X509Certificates {
                [TestFixtureTearDown]
                public void FixtureTearDown ()
                {
-                       cache.Clear ();
+                       if (cache != null)
+                               cache.Clear ();
                        // clean-up, as best as possible, the stores
                }
 
diff --git a/mcs/class/System/Test/compressed.bin b/mcs/class/System/Test/compressed.bin
new file mode 100644 (file)
index 0000000..3098195
Binary files /dev/null and b/mcs/class/System/Test/compressed.bin differ
index d2eea338663d07b6fc49eef39b266b3e0be4246e..69d28f6df916b6ce4641fa4756b97aa24a7ca615 100644 (file)
@@ -1,5 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
-<configuration>
   <system.diagnostics>
     <switches>
       <!-- Boolean switches: any non-zero value is true -->
@@ -22,5 +20,4 @@
       <add name="trace-negative" value="-1"/>
     </switches>
   </system.diagnostics>
-</configuration>
 
diff --git a/mcs/class/System/Test/test-config-file-net-2.0 b/mcs/class/System/Test/test-config-file-net-2.0
deleted file mode 100644 (file)
index 0394048..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<configuration>
-  <system.diagnostics>
-    <sources>
-      <source name="source1" switchName="switch" switchType="System.Diagnostics.SourceSwitch">
-        <!--
-        <listeners>
-          <add name="console" type="System.Diagnostics.ConsoleTraceListener"/>
-        </listeners>
-          -->
-      </source>
-    </sources>
-    <switches>
-      <!-- Boolean switches: any non-zero value is true -->
-      <add name="bool-true" value="1"/>
-      <add name="bool-true-2" value="4"/>
-      <add name="bool-true-3" value="-2"/>
-      <add name="bool-false" value="0"/>
-
-      <!-- trace switches: -->
-      <add name="trace-off" value="0"/>
-      <add name="trace-error" value="1"/>
-      <add name="trace-warning" value="2"/>
-      <add name="trace-info" value="3"/>
-      <add name="trace-verbose" value="4"/>
-
-      <!-- custom switches: -->
-      <add name="custom-switch" value="42"/>
-
-      <!-- this causes problems on .NET -->
-      <add name="trace-negative" value="-1"/>
-    </switches>
-  </system.diagnostics>
-</configuration>
-
index 830e8c0db7ef2be804744d1a794e55acb39b20dd..1351778bb8643b61e65d07e951802ead59e45c29 100644 (file)
@@ -166,7 +166,6 @@ System.Net/ListenerPrefix.cs
 System.Net/MacProxy.cs
 System.Net/MonoHttpDate.cs
 System.Net/NetConfig.cs
-System.Net/NetworkCredential.cs
 System.Net/NtlmClient.cs
 System.Net/RequestStream.cs
 System.Net/ResponseStream.cs
@@ -305,7 +304,6 @@ Mono.Btls/MonoBtlsX509LookupMonoCollection.cs
 Mono.Btls/MonoBtlsX509LookupMono.cs
 Mono.Btls/MonoBtlsX509LookupType.cs
 Mono.Btls/MonoBtlsX509Name.cs
-Mono.Btls/MonoBtlsX509NameList.cs
 Mono.Btls/MonoBtlsX509NameEntryType.cs
 Mono.Btls/MonoBtlsX509Purpose.cs
 Mono.Btls/MonoBtlsX509Revoked.cs
@@ -330,6 +328,7 @@ ReferenceSources/Logging.cs
 ReferenceSources/NativeMethods.cs
 ReferenceSources/RequestCacheProtocol.cs
 ReferenceSources/SettingsSectionInternal.cs
+ReferenceSources/SecureStringHelper.cs
 ReferenceSources/Socket.cs
 ReferenceSources/SR.cs
 ReferenceSources/SRCategoryAttribute.cs
@@ -757,6 +756,7 @@ ReferenceSources/Win32Exception.cs
 ../referencesource/System/net/System/Net/IWebProxyFinder.cs
 ../referencesource/System/net/System/Net/IWebRequestCreate.cs
 ../referencesource/System/net/System/Net/NetworkAccess.cs
+../referencesource/System/net/System/Net/NetworkCredential.cs
 ../referencesource/System/net/System/Net/ProtocolViolationException.cs
 ../referencesource/System/net/System/Net/TransportContext.cs
 ../referencesource/System/net/System/Net/TransportType.cs
index 927528aa2960f68f2974b8f22c8f14feb23731c5..0d885863e40dca27d28abfe999b709dd9758961a 100644 (file)
@@ -1,3 +1,4 @@
+../../test-helpers/NunitHelpers.cs
 WebMatrix.Data/ConnectionEventArgsTests.cs
 WebMatrix.Data/DynamicRecordTests.cs
 ../WebMatrix.Data/DynamicRecord.cs
index 64a199a988f901a3ee633c09c67cb3375e7ac439..620b1628eb850d629601e5a21e78704235dde29f 100644 (file)
@@ -1,3 +1,4 @@
+../../test-helpers/NunitHelpers.cs
 System.Collections.ObjectModel/ObservableCollectionTest.cs
 System.Collections.ObjectModel/ReadOnlyObservableCollectionTest.cs
 System.Collections.Specialized/NotifyCollectionChangedEventArgsTest.cs
diff --git a/mcs/class/corlib/ReferenceSources/SharedStatics.cs b/mcs/class/corlib/ReferenceSources/SharedStatics.cs
deleted file mode 100644 (file)
index 01252cc..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-using System.Threading;
-using StringMaker = System.Security.Util.Tokenizer.StringMaker;
-
-namespace System
-{
-       static class SharedStatics
-       {
-               static StringMaker shared;
-               static public StringMaker GetSharedStringMaker ()
-               {
-                       if (shared == null)
-                               Interlocked.CompareExchange (ref shared, new StringMaker (), null);
-
-                       return shared;
-               }
-
-               static public void ReleaseSharedStringMaker (ref StringMaker maker)
-               {
-
-               }
-       }
-}
\ No newline at end of file
index 30ff8b74bce5a34540a6d9432ced77e7c6beb276..1516216ddc202f9758f32eb7f794620576b18332 100644 (file)
@@ -75,6 +75,13 @@ namespace System.Runtime.InteropServices
                        return false;
                }
 
+               [MonoTODO]
+               public static void CleanupUnusedObjectsInCurrentContext ()
+               {
+                       if (Environment.IsRunningOnWindows)
+                               throw new PlatformNotSupportedException ();
+               }
+
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static IntPtr AllocCoTaskMem (int cb);
                
@@ -789,15 +796,8 @@ namespace System.Runtime.InteropServices
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static string PtrToStringUni (IntPtr ptr, int len);
 
-#if !MOBILE
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static string PtrToStringBSTR (IntPtr ptr);
-#else
-               public static string PtrToStringBSTR (IntPtr ptr)
-               {
-                       throw new NotImplementedException ();
-               }
-#endif
                
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                [ComVisible (true)]
index e74123e761164c93c84fb94dc5720358f08f4537..4f20771c40a57681fa235dfebf59e9bc541910aa 100644 (file)
@@ -416,6 +416,15 @@ public partial class CryptoConfig {
                unresolved_algorithms.Add (nameECDsa_2, defaultECDsa);
                unresolved_algorithms.Add (nameECDsa_3, defaultECDsa);
 
+#if MONODROID
+               algorithms.Add (nameSHA1Cng, defaultSHA1);
+               algorithms.Add (nameSHA256Cng, defaultSHA256);
+               algorithms.Add (nameSHA256Provider, defaultSHA256);
+               algorithms.Add (nameSHA384Cng, defaultSHA384);
+               algorithms.Add (nameSHA384Provider, defaultSHA384);
+               algorithms.Add (nameSHA512Cng, defaultSHA512);
+               algorithms.Add (nameSHA512Provider, defaultSHA512);
+#else
                unresolved_algorithms.Add (nameSHA1Cng, defaultSHA1Cng);
                unresolved_algorithms.Add (nameSHA256Cng, defaultSHA256Cng);
                unresolved_algorithms.Add (nameSHA256Provider, defaultSHA256Provider);
@@ -423,6 +432,7 @@ public partial class CryptoConfig {
                unresolved_algorithms.Add (nameSHA384Provider, defaultSHA384Provider);
                unresolved_algorithms.Add (nameSHA512Cng, defaultSHA512Cng);
                unresolved_algorithms.Add (nameSHA512Provider, defaultSHA512Provider);
+#endif
                Dictionary<string,string> oid = new Dictionary<string, string> (StringComparer.OrdinalIgnoreCase);
 
                // comments here are to match with MS implementation (but not with doc)
index 2e19104a39d81b5d9b92fdc6b2eda620468c3fad..24ada26034cf6194c17cda5df7c382b5f89942a7 100644 (file)
@@ -49,7 +49,8 @@ namespace System.Threading {
                #region Sync with metadata/object-internals.h
                int lock_thread_id;
                // stores a thread handle
-               internal IntPtr system_thread_handle;
+               IntPtr handle;
+               IntPtr native_handle; // used only on Win32
 
                /* Note this is an opaque object (an array), not a CultureInfo */
                private object cached_culture_info;
@@ -92,6 +93,7 @@ namespace System.Threading {
                private IntPtr abort_protected_block_count;
                private int priority = (int) ThreadPriority.Normal;
                private IntPtr owned_mutex;
+               private IntPtr suspended_event;
                /* 
                 * These fields are used to avoid having to increment corlib versions
                 * when a new field is added to the unmanaged MonoThread structure.
@@ -109,11 +111,11 @@ namespace System.Threading {
 
                // Closes the system thread handle
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern void Thread_free_internal(IntPtr handle);
+               private extern void Thread_free_internal();
 
                [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
                ~InternalThread() {
-                       Thread_free_internal(system_thread_handle);
+                       Thread_free_internal();
                }
        }
 
index 13e99d04b9a51c5f33a861c86cdc5a08c727e8be..91e76352ddc10f302f34f9cb9cd50091838fe9f0 100644 (file)
@@ -57,7 +57,7 @@ namespace System {
                 * of icalls, do not require an increment.
                 */
 #pragma warning disable 169
-               private const int mono_corlib_version = 160;
+               private const int mono_corlib_version = 162;
 #pragma warning restore 169
 
                [ComVisible (true)]
index f02a6a7db40e47092dc2b446e020f1dc3992c20f..4ac94d59e1f5ca9594b4cc959290a306015c8506 100644 (file)
@@ -4,10 +4,6 @@ using System.Text;
 using NUnit.Framework;
 using Mono;
 
-#if !MOBILE
-using NUnit.Framework.SyntaxHelpers;
-#endif
-
 namespace MonoTests.Mono {
 
        [TestFixture]
index 70c250d015da682354eb25b303d108380f06759e..75b2de89aac8ac5b700f448ecc8bc970d3bfea0c 100644 (file)
@@ -32,9 +32,6 @@ using System.Collections.Concurrent;
 
 using NUnit;
 using NUnit.Framework;
-#if !MOBILE
-using NUnit.Framework.SyntaxHelpers;
-#endif
 
 namespace MonoTests.System.Collections.Concurrent
 {
index 9cd2d1e11136e2e8cb6841595af01cb0ba7f71e9..4bf774937d5221a767dc1194876eb9e059c817b8 100644 (file)
@@ -30,9 +30,6 @@ using System.Collections.Generic;
 using System.Collections.Concurrent;
 
 using NUnit.Framework;
-#if !MOBILE
-using NUnit.Framework.SyntaxHelpers;
-#endif
 
 namespace MonoTests.System.Collections.Concurrent
 {
index 3ec70c82c26faa1c54f5880b590887d24e4726ca..a343cbe58b51a0360024b6b1f9ef8e64b7d768da 100644 (file)
@@ -68,8 +68,9 @@ namespace MonoTests.System.IO.IsolatedStorageTest {
                public void Constructor_StringMode ()
                {
                        string test = "string-filemode";
-                       IsolatedStorageFileStream isfs = new IsolatedStorageFileStream (test, FileMode.Create);
-                       CheckCommonDetails (test, isfs, true, true);
+                       using (var isfs = new IsolatedStorageFileStream (test, FileMode.Create)) {
+                               CheckCommonDetails (test, isfs, true, true);
+                       }
                }
 
                [Test]
@@ -83,8 +84,9 @@ namespace MonoTests.System.IO.IsolatedStorageTest {
                public void Constructor_StringModeAccess ()
                {
                        string test = "string-filemode-fileaccess";
-                       IsolatedStorageFileStream isfs = new IsolatedStorageFileStream (test, FileMode.Create, FileAccess.ReadWrite);
-                       CheckCommonDetails (test, isfs, true, true);
+                       using (var isfs = new IsolatedStorageFileStream (test, FileMode.Create, FileAccess.ReadWrite)) {
+                               CheckCommonDetails (test, isfs, true, true);
+                       }
                }
 
                [Test]
@@ -98,22 +100,24 @@ namespace MonoTests.System.IO.IsolatedStorageTest {
                public void Constructor_StringModeAccessShare ()
                {
                        string test = "string-filemode-fileaccess-fileshare";
-                       IsolatedStorageFileStream isfs = new IsolatedStorageFileStream (test, FileMode.Create, FileAccess.Write, FileShare.Read);
-                       CheckCommonDetails (test, isfs, false, true);
+                       using (var isfs = new IsolatedStorageFileStream (test, FileMode.Create, FileAccess.Write, FileShare.Read)) {
+                               CheckCommonDetails (test, isfs, false, true);
+                       }
                }
 
                [Test]
                [ExpectedException (typeof (IsolatedStorageException))]
                public void Handle ()
                {
-                       IsolatedStorageFileStream isfs = new IsolatedStorageFileStream ("handle", FileMode.Create);
-                       IntPtr p = isfs.Handle;
+                       using (var isfs = new IsolatedStorageFileStream ("handle", FileMode.Create)) {
+                               IntPtr p = isfs.Handle;
+                       }
                }
 
                [Test]
                public void RootPath ()
                {
-                       new IsolatedStorageFileStream ("/rootpath", FileMode.Create);
+                       new IsolatedStorageFileStream ("/rootpath", FileMode.Create).Close ();
                }
 
                [Test]
index c9d7aca855bc8a1fa9eb64ccd193d34715fd6e38..6a6ecc0b36d66e4bb24febc722b64536c5935179 100644 (file)
@@ -247,8 +247,8 @@ namespace MonoTests.System.Runtime.CompilerServices
                        return res.Result;
                }
 
-#if !MOBILE_STATIC
                [Test]
+               [Ignore ("Incompatible with nunitlite")]
                public void FinishedTaskOnCompleted ()
                {
                        var mres = new ManualResetEvent (false);
@@ -268,12 +268,10 @@ namespace MonoTests.System.Runtime.CompilerServices
 
                        mres.Set ();
                        // this will only terminate correctly if the test was not executed from the main thread
-                       // e.g. Touch.Unit defaults to run tests on the main thread and this will return false
+                       // e.g. nunitlite/Touch.Unit defaults to run tests on the main thread and this will return false
                        Assert.AreEqual (Thread.CurrentThread.IsBackground, mres2.WaitOne (2000), "#2");;
                }
 
-#endif
-
                [Test]
                public void CompletionOnSameCustomSynchronizationContext ()
                {
index 18f58415a1bcc83f89fb9b8bc90f225f7d3de746..51f1797a2b814a7dc77ce0fbb4574cdc0ddf91c8 100644 (file)
@@ -416,7 +416,6 @@ namespace MonoTests.System.Runtime.InteropServices
                }
 
                [Test]
-               [Category ("MobileNotWorking")]
                public void BSTR_Roundtrip ()
                {
                        string s = "mono";
@@ -426,7 +425,6 @@ namespace MonoTests.System.Runtime.InteropServices
                }
 
                [Test]
-               [Category ("MobileNotWorking")]
                public void StringToBSTRWithNullValues ()
                {
                        int size = 128;
@@ -871,6 +869,7 @@ namespace MonoTests.System.Runtime.InteropServices
                );
 #endif
 
+#if !MOBILE_STATIC
                [StructLayout( LayoutKind.Sequential, Pack = 1 )]
                public class FourByteStruct
                {
@@ -1015,6 +1014,7 @@ namespace MonoTests.System.Runtime.InteropServices
 
                        return objResult;
                }
+#endif
        }
 #if !MOBILE
        [ComImport()]
index bf93320e26b9e8abf86b0adc6626960ea76ebcbf..7a0e837cacfc57b227f0c351720ca13007dae4b6 100644 (file)
@@ -9,7 +9,6 @@ using System;
 using System.Security.AccessControl;
 using System.Security.Principal;
 using NUnit.Framework;
-using NUnit.Framework.SyntaxHelpers;
 
 namespace MonoTests.System.Security.AccessControl {
 
index 44830498971db5aa2d87dd3e5274875540a1777f..46fbe94a6d7dab11e3430fbd531b4bfe69f75dd4 100644 (file)
@@ -310,7 +310,7 @@ public class SignatureDescriptionTest {
        public void RSASignatureDescription ()
        {
 // TODO: this would be cleaner with NUnit TestCase'es but they're NUnit 2.5+ :(
-#if FULL_AOT_RUNTIME || MONOTOUCH
+#if FULL_AOT_RUNTIME || MONOTOUCH || MONODROID
                RSASignatureDescriptionCore ("http://www.w3.org/2000/09/xmldsig#rsa-sha1", "System.Security.Cryptography.SHA1Cng", "System.Security.Cryptography.SHA1CryptoServiceProvider");
                RSASignatureDescriptionCore ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", "System.Security.Cryptography.SHA256Cng", "System.Security.Cryptography.SHA256Managed");
                RSASignatureDescriptionCore ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha384", "System.Security.Cryptography.SHA384Cng", "System.Security.Cryptography.SHA384Managed");
@@ -345,4 +345,4 @@ public class SignatureDescriptionTest {
        }
 }
 
-}
\ No newline at end of file
+}
index f35a9d3883062cb04a0eaeeeff65f3ef43dc9116..ea6380d0977fc398fd018736c7ce5ec3fa2a386d 100644 (file)
@@ -10,10 +10,6 @@ using System.Text;
 using NUnit.Framework;
 using NUnit.Framework.Constraints;
 
-#if !MOBILE
-using NUnit.Framework.SyntaxHelpers;
-#endif
-
 namespace MonoTests.System.Text
 {
        [TestFixture]
index 0195967cd3663b36d32cc4de6eb210f73d463c7e..c96da97d9c185eb470a8e1393443981f171ab2f2 100644 (file)
@@ -32,10 +32,6 @@ using System.Text;
 using NUnit.Framework;
 using NUnit.Framework.Constraints;
 
-#if !MOBILE
-using NUnit.Framework.SyntaxHelpers;
-#endif
-
 namespace MonoTests.System.Text
 {
        [TestFixture]
index 474abcd2208084f4ab516897df9e560c0d1d667a..12de999dc5b6372937898c66fdfa1c8d7805b088 100644 (file)
@@ -11,6 +11,7 @@
 
 using NUnit.Framework;
 using System;
+using System.Reflection;
 using System.IO;
 using System.Text;
 
@@ -1042,7 +1043,7 @@ namespace MonoTests.System.Text
                [Category ("MobileNotWorking")]
                public void Bug415628 ()
                {
-                       using (var f = File.Open ("Test/resources/415628.bin", FileMode.Open)) {
+                       using (var f = File.Open (Path.Combine (Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location), "Test/resources/415628.bin"), FileMode.Open)) {
                                BinaryReader br = new BinaryReader (f);
                                byte [] buf = br.ReadBytes (8000);
                                Encoding.UTF8.GetString(buf);
index 903a6946a08163a08687381b77d54f21000ed0d7..94f191a121a4ea80b70c6ae0cf7877824992eb7c 100644 (file)
@@ -30,9 +30,6 @@ using System.Threading;
 using System.Threading.Tasks;
 
 using NUnit.Framework;
-#if !MOBILE
-using NUnit.Framework.SyntaxHelpers;
-#endif
 
 namespace MonoTests.System.Threading.Tasks
 {
index 94d36a131e5ab550770551e7dc0f2d2cffd3163b..1af618d3336965aa43958c7f0370abdf5412cc0e 100644 (file)
@@ -35,9 +35,6 @@ using System.Threading.Tasks;
 using System.Collections.Generic;
 
 using NUnit.Framework;
-#if !MOBILE
-using NUnit.Framework.SyntaxHelpers;
-#endif
 
 namespace MonoTests.System.Threading.Tasks
 {
index 0ca7f49f474c9c6fb8407df5eb41a663090a62c3..803b10c15eb9d4384b89465ad77d1d190bde275e 100644 (file)
@@ -32,9 +32,6 @@ using System.Threading;
 using System.Threading.Tasks;
 
 using NUnit.Framework;
-#if !MOBILE
-using NUnit.Framework.SyntaxHelpers;
-#endif
 
 namespace MonoTests.System.Threading.Tasks
 {
index e8130bc06fd5cf8bac6fc0e3dd06b7d81e841f9e..001f4d454cd80c1b8a9e9c8ea2c921c2bc620e52 100644 (file)
@@ -29,9 +29,6 @@ using System.Threading.Tasks;
 using System.Collections.Generic;
 
 using NUnit.Framework;
-#if !MOBILE
-using NUnit.Framework.SyntaxHelpers;
-#endif
 
 namespace MonoTests.System.Threading.Tasks
 {
index f4e8a9705f78e0beeacafc11313de8475cea8a30..07bd1fe0b56adeee0f7b15ad2b3221e9b307954d 100644 (file)
@@ -34,10 +34,6 @@ using System.Threading.Tasks;
 using System.Collections.Generic;
 using NUnit.Framework;
 
-#if !MOBILE
-using NUnit.Framework.SyntaxHelpers;
-#endif
-
 namespace MonoTests.System.Threading.Tasks
 {
        [TestFixture]
index 8c063dccdc879ca860f78b88fe19806d97ff35bf..b65d150bb581ffb8625456b9525fcab3a28d67c1 100644 (file)
@@ -29,9 +29,6 @@ using System.Threading;
 
 using NUnit;
 using NUnit.Framework;
-#if !MOBILE
-using NUnit.Framework.SyntaxHelpers;
-#endif
 
 namespace MonoTests.System.Threading
 {
index bf3beb47200ad653a5b441ec06d6a6eca21142d9..c4d0bd82fc9f6df28b133379d2db582b68de251d 100644 (file)
@@ -15,10 +15,6 @@ using System.Threading;
 
 using NUnit.Framework;
 
-#if !MOBILE
-using NUnit.Framework.SyntaxHelpers;
-#endif
-
 namespace MonoTests.System
 {
        [TestFixture]
index d70e5fdde709fd20dcbcf54bf9fa7e338d5483bb..4ea4f283bce97cc8e8add2ab8e81dd1891542daf 100644 (file)
@@ -4197,6 +4197,17 @@ namespace MonoTests.System
                        MustTLE (string.Format ("{0}ZZZZ,{1}", typeof (MyRealEnum).FullName, aqn));
                }
 
+               [Test]
+               public void GetTypeExceptionMsg () {
+                       string typeName = "system.int32, foo";
+                       try {
+                               Type.GetType(typeName, true, false);
+                       } catch (TypeLoadException ex) {
+                               Assert.IsTrue (ex.Message.Contains ("system.int32"));
+                               Assert.IsTrue (ex.Message.Contains ("foo"));
+                       }
+               }
+
                delegate void MyAction<in T>(T ag);
 
                [Test] //bug #668506
@@ -4324,6 +4335,24 @@ namespace MonoTests.System
                }
 #endif
 
+
+               [Test]
+               public void GetTypeBadArity()
+               {
+                       // Regression test for #46250
+                       try {
+                               Type.GetType ("System.Collections.Generic.Dictionary`2[System.String]", true);
+                               Assert.Fail ("Did not throw an exception (#1)");
+                       } catch (ArgumentException) {
+                       }
+
+                       try {
+                               Type.GetType ("System.Collections.Generic.Dictionary`2[System.String,System.Int32,System.Int64]", true);
+                               Assert.Fail ("Did not throw an exception (#2)");
+                       } catch (ArgumentException) {
+                       }
+               }
+
                public abstract class Stream : IDisposable
                {
                        public void Dispose ()
index 9ab59b3150348e5d7cd398c3ed89a2c972f6185f..5b3d72dee38d4b94c7c4c2c16179b9d4f6cb729f 100644 (file)
     <Compile Include="..\referencesource\mscorlib\system\security\util\parser.cs" />\r
     <Compile Include="..\referencesource\mscorlib\system\security\util\tokenizer.cs" />\r
     <Compile Include="..\referencesource\mscorlib\system\serializableattribute.cs" />\r
+    <Compile Include="..\referencesource\mscorlib\system\sharedstatics.cs" />\r
     <Compile Include="..\referencesource\mscorlib\system\single.cs" />\r
     <Compile Include="..\referencesource\mscorlib\system\stackoverflowexception.cs" />\r
     <Compile Include="..\referencesource\mscorlib\system\string.cs" />\r
     <Compile Include="ReferenceSources\RuntimeHandles.cs" />\r
     <Compile Include="ReferenceSources\RuntimeType.cs" />\r
     <Compile Include="ReferenceSources\SecurityContext.cs" />\r
-    <Compile Include="ReferenceSources\SharedStatics.cs" />\r
     <Compile Include="ReferenceSources\String.cs" />\r
     <Compile Include="ReferenceSources\TextInfo.cs" />\r
     <Compile Include="ReferenceSources\Type.cs" />\r
index f8107e8c3424f124adfc0df93471b26e460d6ef1..371d01ba4c1628b3105cd3c053802e0a6dab3a84 100644 (file)
@@ -896,7 +896,6 @@ ReferenceSources/CompareInfo.cs
 ReferenceSources/Buffer.cs
 ReferenceSources/TextInfo.cs
 ReferenceSources/win32native.cs
-ReferenceSources/SharedStatics.cs
 ReferenceSources/SecurityContext.cs
 ReferenceSources/PathInternal.cs
 ReferenceSources/BinaryCompatibility.cs
@@ -1024,6 +1023,7 @@ ReferenceSources/Type.cs
 ../referencesource/mscorlib/system/rttype.cs
 ../referencesource/mscorlib/system/sbyte.cs
 ../referencesource/mscorlib/system/serializableattribute.cs
+../referencesource/mscorlib/system/sharedstatics.cs
 ../referencesource/mscorlib/system/stackoverflowexception.cs
 ../referencesource/mscorlib/system/single.cs
 ../referencesource/mscorlib/system/string.cs
index bc43d92b9202a4dd44bdfb2a61ad24b4f04e4e2a..4e444a37efa54a3462c548504d90a02f096fddb2 100644 (file)
@@ -1,3 +1,4 @@
+../../test-helpers/NunitHelpers.cs
 Microsoft.Win32/RegistryKeyTest.cs
 Mono/DataConvertTest.cs
 ../Mono/DataConverter.cs
index 9af81920a16b972c3d4f02f72597a4ba1d85e24d..fa3ffe15ac50e4eeb370f879d42c8af6ccfa69d8 100644 (file)
@@ -47,7 +47,7 @@ namespace MonoTests.Monodoc.Generators
                {
                        var xml = rootTree.RenderUrl ("T:System.String", generator);
                        Assert.IsNotNull (xml);
-                       Assert.IsNotEmpty (xml);
+                       AssertHelper.IsNotEmpty (xml);
                        AssertValidXml (xml);
                        AssertEcmaFullTypeName (xml, "System.String");
                }
@@ -57,7 +57,7 @@ namespace MonoTests.Monodoc.Generators
                {
                        var xml = rootTree.RenderUrl ("T:System.Int32", generator);
                        Assert.IsNotNull (xml);
-                       Assert.IsNotEmpty (xml);
+                       AssertHelper.IsNotEmpty (xml);
                        AssertValidXml (xml);
                        AssertEcmaFullTypeName (xml, "System.Int32");
                }
index 867c9b793898dfb675e3aa05f15da5df70e6ec4c..29da7513704aead3d9f0d098a5b02d737c99e847 100644 (file)
@@ -85,7 +85,7 @@ namespace MonoTests.Monodoc
 
                        // HACK: in reality we have currently 4 known issues which are due to duplicated namespaces across
                        // doc sources, something that was never supported and that we need to improve/fix at some stage
-                       Assert.LessOrEqual (4, errorCount, errorCount + " / " + testCount.ToString ());
+                       AssertHelper.LessOrEqual (4, errorCount, errorCount + " / " + testCount.ToString ());
                }
 
                IEnumerable<Node> GetLeaves (Node node)
index 29ac108da8d5f2db0e007e42b6c721f3116f97fa..fc6bf8da18afd209240b12ab87373ec2b2c57ef5 100644 (file)
@@ -17,7 +17,7 @@ namespace MonoTests.Monodoc
                {
                        // the docPath variable is the only one we know for sure should exist
                        Assert.IsNotNull (Config.Get ("docPath"));
-                       Assert.IsNotEmpty (Config.Get ("docPath"));
+                       AssertHelper.IsNotEmpty (Config.Get ("docPath"));
                }
        }
 }
index b806b8fb6e970302dd755c331a070e831781639a..a3f19b731a01371628deab21a6efcb1866c0df76 100644 (file)
@@ -1,3 +1,4 @@
+../../test-helpers/NunitHelpers.cs
 Monodoc/HelpSourceTests.cs
 Monodoc/EcmaDocTests.cs
 Monodoc/TreeTest.cs
index 06aa93aa15b3494ee32297ef1ffb5ccae85d37d3..3f9b4d7c8c8e538011a29f93c04cee1b8d247adc 100644 (file)
@@ -4,6 +4,10 @@
 // </copyright>
 //------------------------------------------------------------------------------
 
+#if MONO
+#undef FEATURE_PAL
+#endif
+
 namespace System.Net {
 
     using System.IO;
@@ -22,9 +26,11 @@ namespace System.Net {
     /// </devdoc>
     public class NetworkCredential : ICredentials,ICredentialsByHost {
 
+#if FEATURE_MONO_CAS
         private static volatile EnvironmentPermission m_environmentUserNamePermission;
         private static volatile EnvironmentPermission m_environmentDomainNamePermission;
         private static readonly object lockingObject = new object();
+#endif
         private string m_domain;
         private string m_userName;
 #if !FEATURE_PAL
@@ -85,6 +91,7 @@ namespace System.Net {
         }
 #endif //!FEATURE_PAL        
 
+#if FEATURE_MONO_CAS
         void InitializePart1() {
             if (m_environmentUserNamePermission == null) {
                 lock(lockingObject) {
@@ -95,7 +102,7 @@ namespace System.Net {
                 }
             }
         }
-
+#endif
 
         /// <devdoc>
         ///    <para>
@@ -104,8 +111,10 @@ namespace System.Net {
         /// </devdoc>
         public string UserName {
             get {
+#if FEATURE_MONO_CAS
                 InitializePart1();
                 m_environmentUserNamePermission.Demand();
+#endif
                 return InternalGetUserName();
             }
             set {
@@ -124,7 +133,9 @@ namespace System.Net {
         /// </devdoc>
         public string Password {
             get {
+#if FEATURE_MONO_CAS
                 ExceptionHelper.UnmanagedPermission.Demand();
+#endif
                 return InternalGetPassword();
             }
             set {
@@ -151,7 +162,9 @@ namespace System.Net {
         /// </devdoc>
         public SecureString SecurePassword {
             get {
+#if FEATURE_MONO_CAS
                 ExceptionHelper.UnmanagedPermission.Demand();
+#endif
                 return InternalGetSecurePassword().Copy();
             }
             set {
@@ -171,8 +184,10 @@ namespace System.Net {
         /// </devdoc>
         public string Domain {
             get {
+#if FEATURE_MONO_CAS
                 InitializePart1();
                 m_environmentDomainNamePermission.Demand();
+#endif
                 return InternalGetDomain();
             }
             set {
index 87f99a67da32e48e877ea0dd67b3c9870853210a..d455031e761f11b233eb55b65ffbbc57c7164458 100644 (file)
@@ -28,6 +28,15 @@ namespace System {
 
     internal sealed class SharedStatics
     {
+#if MONO
+        // TODO: We are using only GetSharedStringMaker for now which is
+        // ok to be AppDomain static
+        static readonly SharedStatics _sharedStatics = new SharedStatics();
+
+        private SharedStatics()
+        {
+        }
+#else
         // this is declared static but is actually forced to be the same object 
         // for each AppDomain at AppDomain create time.
         private static SharedStatics _sharedStatics;
@@ -38,6 +47,7 @@ namespace System {
         {
             BCLDebug.Assert(false, "SharedStatics..ctor() is never called.");
         }
+#endif
 
         private volatile String _Remoting_Identity_IDGuid;
         public static String Remoting_Identity_IDGuid 
diff --git a/mcs/class/test-helpers/NunitHelpers.cs b/mcs/class/test-helpers/NunitHelpers.cs
new file mode 100644 (file)
index 0000000..f16683e
--- /dev/null
@@ -0,0 +1,112 @@
+using System.IO;
+using System.Collections;
+using NUnit.Framework.Constraints;
+
+namespace NUnit.Framework
+{
+       static class CollectionAssert
+       {
+               public static void DoesNotContain (IEnumerable collection, object val)
+               {
+                        Assert.That(collection, Has.No.Member(val));
+               }
+
+               public static void Contains (IEnumerable collection, object val)
+               {
+                        Assert.That(collection, Has.Member(val));
+               }
+
+               public static void AreEqual (IEnumerable expected, IEnumerable actual, string message = null, params object[] args) 
+               {
+                       Assert.That(actual, Is.EqualTo(expected), message, args);
+               }
+
+               public static void AreEquivalent (IEnumerable expected, IEnumerable actual, string message = null, params object[] args) 
+               {
+                       Assert.That(actual, Is.EquivalentTo(expected), message, args);
+               }
+
+               public static void IsEmpty(IEnumerable collection, string message = null, params object[] args)
+               {
+                       Assert.That(collection, new EmptyCollectionConstraint(), message, args);
+               }
+       }
+
+       static class FileAssert
+       {
+               public static void AreEqual(Stream expected, Stream actual, string message, params object[] args)
+               {
+                       Assert.That(actual, Is.EqualTo(expected), message, args);
+               }
+
+               public static void AreEqual(string expected, string actual, string message, params object[] args)
+               {
+                       using (FileStream exStream = File.OpenRead(expected))
+                       using (FileStream acStream = File.OpenRead(actual))
+                       {
+                               AreEqual(exStream, acStream, message, args);
+                       }
+               }
+       }
+
+       static class StringAssert
+       {
+               public static void Contains(string expected, string actual, string message = null, params object[] args)
+               {
+                       Assert.That(actual, Is.StringContaining (expected), message, args);
+               }
+
+               public static void StartsWith(string expected, string actual, string message = null, params object[] args)
+               {
+                       Assert.IsTrue (actual.StartsWith (expected), message, args);
+               }
+       }
+
+       static class AssertHelper
+       {
+               public static void IsEmpty (string aString, string message = null, params object[] args )
+               {
+                       Assert.That(aString, Is.Empty, message, args);
+               }
+
+               public static void IsNotEmpty (string aString, string message = null, params object[] args )
+               {
+                       Assert.That(aString, Is.Not.Empty, message, args);
+               }
+
+               public static void Less(int arg1, int arg2, string message = null, params object[] args) 
+               {
+                       Assert.That(arg1, Is.LessThan(arg2), message, args);
+               }
+
+               public static void Greater(int arg1, int arg2, string message = null, params object[] args) 
+               {
+                       Assert.That(arg1, Is.GreaterThan(arg2), message, args);
+               }
+
+               public static void Greater(double arg1, double arg2, string message = null, params object[] args) 
+               {
+                       Assert.That(arg1, Is.GreaterThan(arg2), message, args);
+               }
+
+               public static void GreaterOrEqual(int arg1, int arg2, string message = null, params object[] args)
+               {
+                       Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), message, args);
+               }
+
+               public static void GreaterOrEqual(long arg1, long arg2, string message = null, params object[] args)
+               {
+                       Assert.That(arg1, Is.GreaterThanOrEqualTo(arg2), message, args);
+               }
+
+               public static void LessOrEqual (int arg1, int arg2, string message = null, params object[] args)
+               {
+                       Assert.That(arg1, Is.LessThanOrEqualTo(arg2), message, args);
+               }
+
+               public static void IsNotInstanceOfType(System.Type expected, object actual, string message, params object[] args )
+               {
+                       Assert.IsFalse (actual.GetType ().IsInstanceOfType (expected), message, args);
+               }
+       }
+}
diff --git a/mcs/errors/cs1691-2.cs b/mcs/errors/cs1691-2.cs
deleted file mode 100644 (file)
index 8c09699..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-// CS1691: `2' is not a valid warning number
-// Line: 0
-// Compiler options: -warnaserror -warnaserror:1691,2
-
diff --git a/mcs/errors/cs1691-3.cs b/mcs/errors/cs1691-3.cs
deleted file mode 100644 (file)
index c423ebf..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-// CS1691: `20' is not a valid warning number
-// Line: 0
-// Compiler options:  -warnaserror -warnaserror-:20
-
diff --git a/mcs/errors/cs1691-4.cs b/mcs/errors/cs1691-4.cs
deleted file mode 100644 (file)
index cd9ce64..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-// CS1691: `20' is not a valid warning number
-// Line: 0
-// Compiler options: -warnaserror -nowarn:20
-
diff --git a/mcs/errors/cs1691.cs b/mcs/errors/cs1691.cs
deleted file mode 100644 (file)
index bd3e169..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-// CS1691: `1' is not a valid warning number
-// Line: 5
-// Compiler options: -warnaserror
-
-#pragma warning disable 1
-
diff --git a/mcs/errors/cs1744-3.cs b/mcs/errors/cs1744-3.cs
new file mode 100644 (file)
index 0000000..b899816
--- /dev/null
@@ -0,0 +1,18 @@
+// CS1744: Named argument `p1' cannot be used for a parameter which has positional argument specified
+// Line: 8
+
+internal class Program
+{
+       public static void Main ()
+       {
+               Method (1, 2, p1: 3);
+       }
+       
+       static void Method (int p1, int paramNamed, int p2)
+       {
+       }
+       
+       static void Method (int p1, int p2, object paramNamed)
+       {
+       }
+}
diff --git a/mcs/errors/cs1904.cs b/mcs/errors/cs1904.cs
deleted file mode 100644 (file)
index 4417537..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-// CS1904: `4013' is not a valid warning number
-// Line: 0
-// Compiler options: -nowarn:4014,4013
-
-class ClassMain {
-        public static void Main () {}
-}
-
index 6f1b80596d04cf30d046b1c8439575558d1e2283..ad4faf3ce242d67a81f170f9c4620b757e438fac 100644 (file)
@@ -5050,7 +5050,7 @@ namespace Mono.CSharp {
 
                                                                // The slot has been taken by positional argument
                                                                if (temp != null && !(temp is NamedArgument))
-                                                                       break;
+                                                                       return NamedArgumentsMismatch - i - 1;
                                                        }
 
                                                        if (!arg_moved) {
index 47919ec8ce2b5fda133bddbb93509096ba9ef671..0b6fc1abf7722452569bed9c6c1ae75ac2815296 100644 (file)
@@ -254,7 +254,7 @@ namespace Mono.CSharp
                        // Special format which encodes original variable name and
                        // it's scope to support lifted variables debugging. This
                        // is same what csc does and allows to correctly set fields
-                       // scope information (like ambiguity, our of scope, etc).
+                       // scope information (like ambiguity, out of scope, etc).
                        //
                        var id = rc.CurrentBlock.Explicit.GetDebugSymbolScopeIndex ();
                        return "<" + local_info.Name + ">__" + id;
@@ -1067,6 +1067,7 @@ namespace Mono.CSharp
 
                        method.Block = new ToplevelBlock (method.Compiler, method.ParameterInfo, loc,
                                ToplevelBlock.Flags.CompilerGenerated | ToplevelBlock.Flags.NoFlowAnalysis);
+
                        method.Block.AddStatement (new TryFinallyBlockProxyStatement (this, block));
 
                        // Cannot it add to storey because it'd be emitted before nested
index 74bbb46c640cf42053a1d096fd4472a61804934b..afa4f75bd84865f72666678e53685c0c31df5462 100644 (file)
@@ -61,12 +61,10 @@ namespace Mono.CSharp {
                        8009, 8094
                };
 
-               static HashSet<int> AllWarningsHashSet;
-
                public Report (CompilerContext context, ReportPrinter printer)
                {
                        if (context == null)
-                               throw new ArgumentNullException ("settings");
+                               throw new ArgumentNullException ("context");
                        if (printer == null)
                                throw new ArgumentNullException ("printer");
 
@@ -175,18 +173,6 @@ namespace Mono.CSharp {
                        extra_information.Add (msg);
                }
 
-               public bool CheckWarningCode (int code, Location loc)
-               {
-                       if (AllWarningsHashSet == null)
-                               AllWarningsHashSet = new HashSet<int> (AllWarnings);
-
-                       if (AllWarningsHashSet.Contains (code))
-                               return true;
-
-                       Warning (1691, 1, loc, "`{0}' is not a valid warning number", code);
-                       return false;
-               }
-
                public void ExtraInformation (Location loc, string msg)
                {
                        extra_information.Add (String.Format ("{0} {1}", loc, msg));
@@ -1109,8 +1095,7 @@ namespace Mono.CSharp {
 
                public void WarningDisable (Location location, int code, Report Report)
                {
-                       if (Report.CheckWarningCode (code, location))
-                               regions.Add (new Disable (location.Row, code));
+                       regions.Add (new Disable (location.Row, code));
                }
 
                public void WarningEnable (int line)
@@ -1120,9 +1105,6 @@ namespace Mono.CSharp {
 
                public void WarningEnable (Location location, int code, CompilerContext context)
                {
-                       if (!context.Report.CheckWarningCode (code, location))
-                               return;
-
                        if (context.Settings.IsWarningDisabledGlobally (code))
                                context.Report.Warning (1635, 1, location, "Cannot restore warning `CS{0:0000}' because it was disabled globally", code);
 
index 63c6c41d516971168f969c39e4c1f75b1e73ba36..1393bcd58f35bc0459f771ca8be3d0c9b3f6bb5a 100644 (file)
@@ -583,7 +583,6 @@ namespace Mono.CSharp {
 
                public bool ProcessWarningsList (string text, Action<int> action)
                {
-                       bool valid = true;
                        foreach (string wid in text.Split (numeric_value_separator, StringSplitOptions.RemoveEmptyEntries)) {
                                var warning = wid;
                                if (warning.Length == 6 && warning [0] == 'C' && warning [1] == 'S')
@@ -594,15 +593,10 @@ namespace Mono.CSharp {
                                        continue;
                                }
 
-                               if (report.CheckWarningCode (id, Location.Null)) {
-                                       action (id);
-                               } else {
-                                       report.Error (1904, "`{0}' is not a valid warning number", wid);
-                                       valid = false;
-                               }
+                               action (id);
                        }
 
-                       return valid;
+                       return true;
                }
 
                void Error_RequiresArgument (string option)
@@ -1242,6 +1236,8 @@ namespace Mono.CSharp {
                        case "/appconfig":
                        case "/baseaddress":
                        case "/deterministic":
+                       case "/deterministic+":
+                       case "/deterministic-":
                        case "/errorendlocation":
                        case "/errorlog":
                        case "/features":
index eab87d16a17871ef5789fd98503ec70a99708f86..fbb060f52960da9af8218171c9cf6991e8b102cc 100644 (file)
@@ -3245,9 +3245,10 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       if (Parent != null) {
-                               // TODO: It's needed only when scope has variable (normal or lifted)
-                               ec.BeginScope (GetDebugSymbolScopeIndex ());
+                       // TODO: It's needed only when scope has variable (normal or lifted)
+                       var scopeIndex = GetDebugSymbolScopeIndex ();
+                       if (scopeIndex > 0) {
+                               ec.BeginScope (scopeIndex);
                        }
 
                        EmitScopeInitialization (ec);
@@ -3258,7 +3259,7 @@ namespace Mono.CSharp {
 
                        DoEmit (ec);
 
-                       if (Parent != null)
+                       if (scopeIndex > 0)
                                ec.EndScope ();
 
                        if (ec.EmitAccurateDebugInfo && HasReachableClosingBrace && !(this is ParametersBlock) &&
@@ -3451,7 +3452,12 @@ namespace Mono.CSharp {
                        storey.Parent.PartialContainer.AddCompilerGeneratedClass (storey);
                }
 
-               public int GetDebugSymbolScopeIndex ()
+               public void DisableDebugScopeIndex ()
+               {
+                       debug_scope_index = -1;
+               }
+
+               public virtual int GetDebugSymbolScopeIndex ()
                {
                        if (debug_scope_index == 0)
                                debug_scope_index = ++ParametersBlock.debug_scope_index;
@@ -3859,6 +3865,11 @@ namespace Mono.CSharp {
                        return res;
                }
 
+               public override int GetDebugSymbolScopeIndex ()
+               {
+                       return 0;
+               }
+
                public LabeledStatement GetLabel (string name, Block block)
                {
                        //
@@ -8338,15 +8349,14 @@ namespace Mono.CSharp {
                        ec.LoopBegin = ec.DefineLabel ();
                        ec.LoopEnd = ec.DefineLabel ();
 
-                       if (!(Statement is Block))
-                               ec.BeginCompilerScope (variable.Block.Explicit.GetDebugSymbolScopeIndex ());
+                       ec.BeginCompilerScope (variable.Block.Explicit.GetDebugSymbolScopeIndex ());
+                       body.Explicit.DisableDebugScopeIndex ();
 
                        variable.CreateBuilder (ec);
 
                        Statement.Emit (ec);
 
-                       if (!(Statement is Block))
-                               ec.EndScope ();
+                       ec.EndScope ();
 
                        ec.LoopBegin = old_begin;
                        ec.LoopEnd = old_end;
index db740c2456f8f89c415ad5d6ed13f835ade27ad1..d14a377f00fc9f23f40ad4633e7bc5617f6201d7 100644 (file)
       </locals>
       <scopes>
         <entry index="0" start="0x1" end="0x1e" />
-        <entry index="1" start="0xb" end="0x11" />
-        <entry index="2" start="0xf" end="0x10" />
+        <entry index="1" start="0xf" end="0x10" />
       </scopes>
     </method>
     <method token="0x6000019">
       </locals>
       <scopes>
         <entry index="0" start="0x1" end="0x37" />
-        <entry index="1" start="0xe" end="0x18" />
-        <entry index="2" start="0x16" end="0x17" />
+        <entry index="1" start="0x16" end="0x17" />
       </scopes>
     </method>
     <method token="0x600001a">
       </locals>
       <scopes>
         <entry index="0" start="0x1" end="0x3c" />
-        <entry index="1" start="0xf" end="0x18" />
-        <entry index="2" start="0x16" end="0x17" />
+        <entry index="1" start="0x16" end="0x17" />
       </scopes>
     </method>
     <method token="0x600001b">
       </locals>
       <scopes>
         <entry index="0" start="0x1" end="0x4d" />
-        <entry index="1" start="0x24" end="0x31" />
-        <entry index="2" start="0x2f" end="0x30" />
+        <entry index="1" start="0x2f" end="0x30" />
       </scopes>
     </method>
   </methods>
index 3958eb589f82a1a044189259b56b365b575b8d74..41445be8cee95dca28411f414d9893332c8fae87 100644 (file)
@@ -83,7 +83,8 @@
       </sequencepoints>
       <locals />
       <scopes>
-        <entry index="0" start="0x0" end="0xb" />
+        <entry index="0" start="0x0" end="0x0" />
+        <entry index="1" start="0x0" end="0xb" />
       </scopes>
     </method>
   </methods>
index 1038be00dde8b9d78e423fe0197ab430a7661d3e..c823a34e298adbe4cf07c325c957aa767c639503 100644 (file)
@@ -28,9 +28,7 @@
       </locals>
       <scopes>
         <entry index="0" start="0x1" end="0x1c" />
-        <entry index="1" start="0xb" end="0xf" />
-        <entry index="2" start="0x1c" end="0x3f" />
-        <entry index="3" start="0x28" end="0x2e" />
+        <entry index="1" start="0x1c" end="0x3f" />
       </scopes>
     </method>
     <method token="0x6000003">
diff --git a/mcs/tests/test-debug-31-ref.xml b/mcs/tests/test-debug-31-ref.xml
new file mode 100644 (file)
index 0000000..1a77894
--- /dev/null
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<symbols>
+  <files>
+    <file id="1" name="test-debug-31.cs" checksum="e1579371d047d82b8d90c0dc26393808" />
+  </files>
+  <methods>
+    <method token="0x6000001">
+      <sequencepoints />
+      <locals />
+      <scopes />
+    </method>
+    <method token="0x6000002">
+      <sequencepoints>
+        <entry il="0x0" row="8" col="3" file_ref="1" hidden="false" />
+        <entry il="0x1" row="9" col="4" file_ref="1" hidden="false" />
+        <entry il="0x20" row="11" col="4" file_ref="1" hidden="false" />
+        <entry il="0x21" row="11" col="25" file_ref="1" hidden="false" />
+        <entry il="0x2a" row="11" col="13" file_ref="1" hidden="false" />
+        <entry il="0x2e" row="12" col="4" file_ref="1" hidden="false" />
+        <entry il="0x2f" row="13" col="5" file_ref="1" hidden="false" />
+        <entry il="0x30" row="13" col="13" file_ref="1" hidden="false" />
+        <entry il="0x35" row="14" col="4" file_ref="1" hidden="false" />
+        <entry il="0x36" row="11" col="25" file_ref="1" hidden="false" />
+        <entry il="0x43" row="16" col="4" file_ref="1" hidden="false" />
+        <entry il="0x44" row="16" col="26" file_ref="1" hidden="false" />
+        <entry il="0x4f" row="16" col="13" file_ref="1" hidden="false" />
+        <entry il="0x56" row="16" col="33" file_ref="1" hidden="false" />
+        <entry il="0x57" row="17" col="5" file_ref="1" hidden="false" />
+        <entry il="0x59" row="17" col="13" file_ref="1" hidden="false" />
+        <entry il="0x5e" row="18" col="4" file_ref="1" hidden="false" />
+        <entry il="0x5f" row="16" col="26" file_ref="1" hidden="false" />
+        <entry il="0x70" row="20" col="4" file_ref="1" hidden="false" />
+        <entry il="0x71" row="20" col="26" file_ref="1" hidden="false" />
+        <entry il="0x7c" row="20" col="13" file_ref="1" hidden="false" />
+        <entry il="0x83" row="20" col="33" file_ref="1" hidden="false" />
+        <entry il="0x84" row="21" col="5" file_ref="1" hidden="false" />
+        <entry il="0x86" row="21" col="13" file_ref="1" hidden="false" />
+        <entry il="0x8b" row="22" col="4" file_ref="1" hidden="false" />
+        <entry il="0x8c" row="20" col="26" file_ref="1" hidden="false" />
+        <entry il="0x9d" row="23" col="3" file_ref="1" hidden="false" />
+      </sequencepoints>
+      <locals>
+        <entry name="array" il_index="0" scope_ref="0" />
+        <entry name="item" il_index="1" scope_ref="1" />
+        <entry name="item1" il_index="4" scope_ref="3" />
+        <entry name="item2" il_index="7" scope_ref="5" />
+      </locals>
+      <scopes>
+        <entry index="0" start="0x20" end="0x43" />
+        <entry index="1" start="0x2e" end="0x35" />
+        <entry index="2" start="0x43" end="0x70" />
+        <entry index="3" start="0x56" end="0x5e" />
+        <entry index="4" start="0x70" end="0x9d" />
+        <entry index="5" start="0x83" end="0x8b" />
+      </scopes>
+    </method>
+  </methods>
+</symbols>
\ No newline at end of file
diff --git a/mcs/tests/test-debug-31.cs b/mcs/tests/test-debug-31.cs
new file mode 100644 (file)
index 0000000..5a3d55d
--- /dev/null
@@ -0,0 +1,25 @@
+using System;
+
+namespace cp534534
+{
+       class MainClass
+       {
+               public static void Main ()
+               {
+                       var array = new string[] { "a", "b", "c" };
+                       
+                       foreach (var item in array)
+                       {
+                               Console.WriteLine (item);
+                       }
+
+                       foreach (var item1 in array) {
+                               Console.WriteLine (item1);
+                       }
+
+                       foreach (var item2 in array) {
+                               Console.WriteLine (item2);
+                       }
+               }
+       }
+}
\ No newline at end of file
diff --git a/mcs/tests/test-debug-32-ref.xml b/mcs/tests/test-debug-32-ref.xml
new file mode 100644 (file)
index 0000000..acabcfb
--- /dev/null
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8"?>
+<symbols>
+  <files>
+    <file id="1" name="test-debug-32.cs" checksum="71a5517624c6bd01871fcb9ae65242b7" />
+  </files>
+  <methods>
+    <method token="0x6000001">
+      <sequencepoints />
+      <locals />
+      <scopes />
+    </method>
+    <method token="0x6000002">
+      <sequencepoints />
+      <locals />
+      <scopes />
+    </method>
+    <method token="0x6000003">
+      <sequencepoints>
+        <entry il="0x0" row="19" col="2" file_ref="1" hidden="false" />
+        <entry il="0x1" row="20" col="2" file_ref="1" hidden="false" />
+      </sequencepoints>
+      <locals />
+      <scopes />
+    </method>
+    <method token="0x6000004">
+      <sequencepoints />
+      <locals />
+      <scopes />
+    </method>
+    <method token="0x6000005">
+      <sequencepoints>
+        <entry il="0x27" row="6" col="2" file_ref="1" hidden="false" />
+        <entry il="0x28" row="7" col="3" file_ref="1" hidden="false" />
+        <entry il="0x43" row="9" col="3" file_ref="1" hidden="false" />
+        <entry il="0x4a" row="10" col="3" file_ref="1" hidden="false" />
+        <entry il="0x59" row="10" col="7" file_ref="1" hidden="false" />
+        <entry il="0x5a" row="11" col="4" file_ref="1" hidden="false" />
+        <entry il="0x7c" row="12" col="3" file_ref="1" hidden="false" />
+        <entry il="0x8d" row="16" col="2" file_ref="1" hidden="false" />
+      </sequencepoints>
+      <locals />
+      <scopes>
+        <entry index="0" start="0x59" end="0x7c" />
+      </scopes>
+    </method>
+    <method token="0x6000006">
+      <sequencepoints />
+      <locals />
+      <scopes />
+    </method>
+    <method token="0x6000007">
+      <sequencepoints />
+      <locals />
+      <scopes />
+    </method>
+    <method token="0x6000008">
+      <sequencepoints />
+      <locals />
+      <scopes />
+    </method>
+    <method token="0x6000009">
+      <sequencepoints />
+      <locals />
+      <scopes />
+    </method>
+    <method token="0x600000a">
+      <sequencepoints />
+      <locals />
+      <scopes />
+    </method>
+    <method token="0x600000b">
+      <sequencepoints />
+      <locals />
+      <scopes />
+    </method>
+    <method token="0x600000c">
+      <sequencepoints>
+        <entry il="0x0" row="12" col="13" file_ref="1" hidden="false" />
+        <entry il="0x1" row="13" col="4" file_ref="1" hidden="false" />
+        <entry il="0xd" row="13" col="16" file_ref="1" hidden="false" />
+        <entry il="0xe" row="14" col="4" file_ref="1" hidden="false" />
+        <entry il="0xf" row="15" col="3" file_ref="1" hidden="false" />
+      </sequencepoints>
+      <locals />
+      <scopes>
+        <entry index="0" start="0x0" end="0x0" />
+        <entry index="1" start="0x0" end="0xf" />
+        <entry index="2" start="0xd" end="0xe" />
+      </scopes>
+    </method>
+  </methods>
+</symbols>
\ No newline at end of file
diff --git a/mcs/tests/test-debug-32.cs b/mcs/tests/test-debug-32.cs
new file mode 100644 (file)
index 0000000..ba52a10
--- /dev/null
@@ -0,0 +1,21 @@
+using System.Collections.Generic;
+
+class X
+{
+       internal static IEnumerable<int> EnumerateKind ()
+       {
+               yield return 1;
+
+               int h = 3;
+               try {
+                       yield return h;
+               } finally {
+                       if (h != 1) {
+                       }
+               }
+       }
+
+       public static void Main ()
+       {
+       }
+}
\ No newline at end of file
diff --git a/mcs/tests/test-named-10.cs b/mcs/tests/test-named-10.cs
new file mode 100644 (file)
index 0000000..6434c83
--- /dev/null
@@ -0,0 +1,18 @@
+using System;
+
+internal class Program
+{
+       public static void Main ()
+       {
+               Method (1, 2, paramNamed: 3);
+       }
+       
+       static void Method (int p1, int paramNamed, int p2)
+       {
+               throw new ApplicationException ();
+       }
+       
+       static void Method (int p1, int p2, object paramNamed)
+       {
+       }
+}
index 56e35f7709f857723d5c158e14535337098d1e93..f9c8f8b2465c7c00ddc1831c311422c9785ad594 100644 (file)
       </method>
     </type>
   </test>
+  <test name="test-debug-31.cs">
+    <type name="cp534534.MainClass">
+      <method name="Void Main()" attrs="150">
+        <size>158</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
+  <test name="test-debug-32.cs">
+    <type name="X">
+      <method name="System.Collections.Generic.IEnumerable`1[System.Int32] EnumerateKind()" attrs="147">
+        <size>23</size>
+      </method>
+      <method name="Void Main()" attrs="150">
+        <size>2</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="X+&lt;EnumerateKind&gt;c__Iterator0">
+      <method name="Boolean MoveNext()" attrs="486">
+        <size>152</size>
+      </method>
+      <method name="Int32 System.Collections.Generic.IEnumerator&lt;int&gt;.get_Current()" attrs="2529">
+        <size>14</size>
+      </method>
+      <method name="System.Object System.Collections.IEnumerator.get_Current()" attrs="2529">
+        <size>19</size>
+      </method>
+      <method name="Void Dispose()" attrs="486">
+        <size>57</size>
+      </method>
+      <method name="Void Reset()" attrs="486">
+        <size>6</size>
+      </method>
+      <method name="System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()" attrs="481">
+        <size>14</size>
+      </method>
+      <method name="System.Collections.Generic.IEnumerator`1[System.Int32] System.Collections.Generic.IEnumerable&lt;int&gt;.GetEnumerator()" attrs="481">
+        <size>26</size>
+      </method>
+      <method name="Void &lt;&gt;__Finally0()" attrs="129">
+        <size>17</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="test-decl-expr-01.cs">
     <type name="DeclarationExpression">
       <method name="Int32 Main()" attrs="150">
       </method>
     </type>
   </test>
+  <test name="test-named-10.cs">
+    <type name="Program">
+      <method name="Void Main()" attrs="150">
+        <size>15</size>
+      </method>
+      <method name="Void Method(Int32, Int32, Int32)" attrs="145">
+        <size>7</size>
+      </method>
+      <method name="Void Method(Int32, Int32, System.Object)" attrs="145">
+        <size>2</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="test-nameof-01.cs">
     <type name="X">
       <method name="Int32 Main()" attrs="150">
index bb93b0e0619a7043094c3271509202193411337d..eacdad812b89f09c4cb9371f32d2469e08689cc3 100644 (file)
@@ -33,9 +33,6 @@
     <Reference Include="System" />\r
     <Reference Include="System.Core" />\r
     <Reference Include="System.Xml" />\r
-    <Reference Include="Mono.Cecil">\r
-      <HintPath>..\..\class\lib\net_4_x\Mono.Cecil.dll</HintPath>\r
-    </Reference>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <Compile Include="AssemblyResolver.cs" />\r
     <Compile Include="..\..\class\Mono.Options\Mono.Options\Options.cs">\r
       <Link>Options.cs</Link>\r
     </Compile>\r
+\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil.Cil\*.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil.Metadata\*.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil.PE\*.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\ArrayType.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\AssemblyDefinition.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\AssemblyFlags.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\AssemblyHashAlgorithm.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\AssemblyLinkedResource.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\AssemblyNameDefinition.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\AssemblyNameReference.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\AssemblyReader.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\AssemblyWriter.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\BaseAssemblyResolver.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\CallSite.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\CustomAttribute.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\DefaultAssemblyResolver.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\EmbeddedResource.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\EventAttributes.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\EventDefinition.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\EventReference.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\ExportedType.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\FieldAttributes.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\FieldDefinition.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\FieldReference.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\FileAttributes.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\FunctionPointerType.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\GenericInstanceMethod.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\GenericInstanceType.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\GenericParameter.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\GenericParameterAttributes.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\IConstantProvider.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\ICustomAttributeProvider.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\IGenericInstance.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\IGenericParameterProvider.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\IMarshalInfoProvider.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\IMemberDefinition.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\IMetadataScope.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\IMetadataTokenProvider.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\IMethodSignature.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\Import.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\LinkedResource.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\ManifestResourceAttributes.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\MarshalInfo.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\MemberDefinitionCollection.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\MemberReference.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\MetadataResolver.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\MetadataSystem.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\MethodAttributes.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\MethodCallingConvention.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\MethodDefinition.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\MethodImplAttributes.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\MethodReference.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\MethodReturnType.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\MethodSemanticsAttributes.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\MethodSpecification.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\Modifiers.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\ModuleDefinition.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\ModuleKind.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\ModuleReference.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\NativeType.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\ParameterAttributes.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\ParameterDefinition.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\ParameterDefinitionCollection.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\ParameterReference.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\PinnedType.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\PInvokeAttributes.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\PInvokeInfo.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\PointerType.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\PropertyAttributes.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\PropertyDefinition.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\PropertyReference.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\ReferenceType.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\Resource.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\SecurityDeclaration.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\SentinelType.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\TargetRuntime.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\Treatments.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\TypeAttributes.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\TypeDefinition.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\TypeDefinitionCollection.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\TypeParser.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\TypeReference.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\TypeSpecification.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\TypeSystem.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\VariantType.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Cecil\WindowsRuntimeProjections.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Collections.Generic\*.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono.Security.Cryptography\*.cs" />\r
+    <Compile Include="..\..\..\external\cecil\Mono\*.cs" />    \r
   </ItemGroup>\r
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />\r
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r
index 8b87256f6a7452f58ba98e0118e15099aa437981..769a38ad5b2b2ce4d3bb5a81bc20b30dbaa23686 100644 (file)
@@ -12,7 +12,7 @@ Mono.Linker.Tests.dll.sources:
        find Mono.Linker.Tests -name "*.cs" > Mono.Linker.Tests.dll.sources
 
 Mono.Linker.Tests.dll: Mono.Cecil.dll monolinker.exe Mono.Linker.Tests.dll.sources
-       $(MCS) /target:library /out:Mono.Linker.Tests.dll /r:nunit.framework.dll /r:Mono.Cecil.dll /r:monolinker.exe @Mono.Linker.Tests.dll.sources
+       $(MCS) /target:library /out:Mono.Linker.Tests.dll /r:nunitlite.dll /r:Mono.Cecil.dll /r:monolinker.exe @Mono.Linker.Tests.dll.sources
 
 clean:
        rm -rf Mono.Cecil.dll monolinker.exe Mono.Linker.Tests.dll.sources Mono.Linker.Tests.dll
index e1c55c1f0a52f1e9e7a30de32d7b01b8d08c199a..18aa8cf854f508eb4660b9887f68cf8a8f13e83b 100644 (file)
@@ -2,7 +2,7 @@ thisdir = tools/mono-api-html
 SUBDIRS =
 include ../../build/rules.make
 
-LIB_REFS = Mono.Cecil System.Xml System.Core System System.Xml.Linq
+LIB_REFS = System.Xml System.Core System System.Xml.Linq
 LOCAL_MCS_FLAGS =
 
 PROGRAM = mono-api-html.exe
index d62e483a1c89f51536e3a9681e72bbbb234e30e6..4fce01cd94229c2ef2859e58c3f05bbc8d38c5f9 100644 (file)
       <Project>{2CA6026B-2DC8-4C4C-A12C-1E8234049DB7}</Project>\r
       <Name>corlib-net_4_x</Name>\r
     </ProjectReference>\r
-    <ProjectReference Include="../../class/legacy/Mono.Cecil/Mono.Cecil-net_4_x.csproj">\r
-      <Project>{6DE38817-EC25-433A-AE58-0D30C5E6C460}</Project>\r
-      <Name>Mono.Cecil-net_4_x</Name>\r
-    </ProjectReference>\r
     <ProjectReference Include="../../class/System.XML/System.Xml-net_4_x.csproj">\r
       <Project>{87FD2F0F-5222-4AE6-BD63-2D4975E11E5B}</Project>\r
       <Name>System.Xml-net_4_x</Name>\r
diff --git a/mcs/tools/nunit-lite/NUnitLite/BabysitterSupport.cs b/mcs/tools/nunit-lite/NUnitLite/BabysitterSupport.cs
new file mode 100644 (file)
index 0000000..86c44d9
--- /dev/null
@@ -0,0 +1,113 @@
+//
+// BabysitterSupport.cs: Nunit extensions to support test harness used by Mono.
+//                       See scripts/babysitter in Mono repository.
+//
+// Author:
+//   Andi McClure (andi.mcclure@xamarin.com)
+//
+// Copyright (C) 2015 Xamarin, Inc (http://www.xamarin.com)
+//
+
+namespace Xamarin
+{
+       using System;
+       using System.IO;
+       using System.Collections.Generic;
+       using NUnit.Framework.Api;
+       using NUnit.Framework.Internal;
+       using NUnit.Framework.Internal.Filters;
+
+       public class BabysitterSupport
+       {
+               enum OverrideMode {None, Run, Exclude};
+               public static Dictionary<string, bool> OverrideTests = new Dictionary<string, bool>();
+               private static OverrideMode Override = OverrideMode.None;
+               private static string CurrentTestFile = null, RanTestFile = null, FailedTestFile = null;
+
+               private static void DeleteFile(string path)
+               {
+                       try {
+                               File.Delete(path);
+                       } catch (Exception) {}
+               }
+               private static void WriteFile(string path, string contents)
+               {
+                       DeleteFile(path);
+                       File.AppendAllText(path, contents);
+               }
+
+               // Environment variables are available from process start, so safe to do setup in a static constructor
+               static BabysitterSupport()
+               {
+                       string overrideModeString = Environment.GetEnvironmentVariable("MONO_BABYSITTER_NUNIT_RUN_MODE");
+                       string overrideTestString = Environment.GetEnvironmentVariable("MONO_BABYSITTER_NUNIT_RUN_TEST");
+                       if (overrideModeString == "RUN")
+                               Override = OverrideMode.Run;
+                       else if (overrideModeString == "EXCLUDE")
+                               Override = OverrideMode.Exclude;
+                       if (Override != OverrideMode.None)
+                       {
+                               string[] overrideTests = overrideTestString.Split(new char[] {';'}, StringSplitOptions.RemoveEmptyEntries);
+                               foreach (string s in overrideTests)
+                                       OverrideTests[s] = true;
+                       }
+
+                       CurrentTestFile = Environment.GetEnvironmentVariable("MONO_BABYSITTER_NUNIT_CURRENT_TEST_FILE");
+                       RanTestFile = Environment.GetEnvironmentVariable("MONO_BABYSITTER_NUNIT_RAN_TEST_FILE");
+                       FailedTestFile = Environment.GetEnvironmentVariable("MONO_BABYSITTER_NUNIT_FAILED_TEST_FILE");
+               }
+
+               // Entry points
+
+               public static void RecordEnterTest( string testName )
+               {
+                       if (CurrentTestFile != null)
+                               WriteFile(CurrentTestFile, testName);
+                       if (RanTestFile != null)
+                               File.AppendAllText(RanTestFile, testName + Environment.NewLine);
+               }
+
+               public static void RecordLeaveTest( string testName )
+               {
+                       if (CurrentTestFile != null)
+                               DeleteFile(CurrentTestFile);
+               }
+
+               public static void RecordFailedTest( string testName )
+               {
+                       if (FailedTestFile != null)
+                               File.AppendAllText(FailedTestFile, testName + Environment.NewLine);
+               }
+
+               public static ITestFilter AddBabysitterFilter(ITestFilter currentFilter)
+               {
+                       if (Override == OverrideMode.None)
+                               return currentFilter;
+                       return new AndFilter(currentFilter, new BabysitterFilter());
+               }
+
+               [Serializable]
+               private class BabysitterFilter : TestFilter
+               {
+                       public override bool Match(ITest test)
+                       {
+                               if (test.IsSuite) // A suite returning true will automatically run ALL contents, filters ignored
+                                       return false;
+                               bool inList = OverrideTests.ContainsKey(test.FullName);
+                               bool allow = true;
+                               switch (Override)
+                               {
+                                       case OverrideMode.None:
+                                               break;
+                                       case OverrideMode.Run:
+                                               allow = inList;
+                                               break;
+                                       case OverrideMode.Exclude:
+                                               allow = !inList;
+                                               break;
+                               }
+                               return allow;
+                       }
+               }
+       }
+}
\ No newline at end of file
index e205091b942ff3177cecef28d2d4a2e966125d4d..edf8c1283791bde051589c5199693cb6ad1014ba 100644 (file)
 ../../../../external/nunit-lite/NUnitLite-1.0.0/src/framework/TestCaseData.cs
 ../../../../external/nunit-lite/NUnitLite-1.0.0/src/framework/TestContext.cs
 ../../../../external/nunit-lite/NUnitLite-1.0.0/src/framework/Throws.cs
+BabysitterSupport.cs
diff --git a/mcs/tools/nunit-lite/nunit-lite-console/nunit-lite-console.exe.config b/mcs/tools/nunit-lite/nunit-lite-console/nunit-lite-console.exe.config
deleted file mode 100644 (file)
index 2ccc2b9..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>\r
-<configuration>\r
- <runtime>\r
- <!-- \r
-   This is necessary to prevent the runner from terminating on\r
-   any unhandled exceptions which occur. We account for unhandled exceptions on\r
-   other threads with an event handler, but would still be terminated using the\r
-   new behavior.\r
- -->\r
-   <legacyUnhandledExceptionPolicy enabled="1" />\r
-  </runtime>\r
-</configuration>\r
diff --git a/mcs/tools/nunit-lite/nunit-lite-console/nunit-lite-console.exe.config.tmpl b/mcs/tools/nunit-lite/nunit-lite-console/nunit-lite-console.exe.config.tmpl
new file mode 100644 (file)
index 0000000..bc218db
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<configuration>\r
+  <!-- __INSERT_CUSTOM_APP_CONFIG_GLOBAL__ -->\r
+  <runtime>\r
+    <!-- \r
+      This is necessary to prevent the runner from terminating on\r
+      any unhandled exceptions which occur. We account for unhandled exceptions on\r
+      other threads with an event handler, but would still be terminated using the\r
+      new behavior.\r
+    -->\r
+    <legacyUnhandledExceptionPolicy enabled="1" />\r
+    <!-- __INSERT_CUSTOM_APP_CONFIG_RUNTIME__ -->\r
+  </runtime>\r
+</configuration>\r
index 9d6e914532dad6265dc577dd2bbe6c0e176d5895..ca06717b19b63e665d09a4bf6f15c48bc6b2a605 100644 (file)
@@ -131,6 +131,7 @@ install-pcl5-framework:
 EXTRA_DISTFILES = \
        data/xbuild.rsp \
        data/xbuild.exe.config.in \
+       data/xbuild.exe.config_test.in \
        data/Microsoft.Build.xsd \
        data/2.0/Microsoft.Common.tasks \
        data/3.5/Microsoft.Common.tasks \
diff --git a/mcs/tools/xbuild/data/xbuild.exe.config_test.in b/mcs/tools/xbuild/data/xbuild.exe.config_test.in
new file mode 100644 (file)
index 0000000..a90dbf2
--- /dev/null
@@ -0,0 +1,11 @@
+       <generatePublisherEvidence enabled="false" />
+       <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+               <dependentAssembly>
+                       <assemblyIdentity name="Microsoft.Build.Framework" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+                       <bindingRedirect oldVersion="0.0.0.0-100.0.0.0" newVersion="@ASM_VERSION@" />
+               </dependentAssembly>
+               <dependentAssembly>
+                       <assemblyIdentity name="Microsoft.Build.Engine" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+                       <bindingRedirect oldVersion="0.0.0.0-100.0.0.0" newVersion="@ASM_VERSION@" />
+               </dependentAssembly>
+       </assemblyBinding>
index 9dcf0987ec86b7daeadd7c92e899af2c823b82ea..4c503c060ac3b432270f45b7367477750751875d 100644 (file)
@@ -9,7 +9,7 @@ export XBUILD_FRAMEWORK_FOLDERS_PATH= $(topdir)/class/Microsoft.Build/xbuild-tes
 ifeq (4.0, $(FRAMEWORK_VERSION))
 NO_TEST=true
 else
-test-local: copy-targets $(test_lib).config
+test-local: copy-targets Test/test-config-file-$(PROFILE)
 clean-local: clean-targets clean-test-config
 endif
 
@@ -17,11 +17,11 @@ xbuild-net4-fail:
        @echo "The net_4_0 profile contains reference assemblies only and cannot be installed/tested as an xbuild toolset"
        @exit 1
 
-$(test_lib).config: $(XBUILD_DATA_DIR)/xbuild.exe.config.in
-       sed -e 's/@ASM_VERSION@/$(XBUILD_ASSEMBLY_VERSION)/g' $(XBUILD_DATA_DIR)/xbuild.exe.config.in > $(test_lib).config
+Test/test-config-file-$(PROFILE): $(XBUILD_DATA_DIR)/xbuild.exe.config_test.in
+       sed -e 's/@ASM_VERSION@/$(XBUILD_ASSEMBLY_VERSION)/g' $(XBUILD_DATA_DIR)/xbuild.exe.config_test.in > Test/test-config-file-$(PROFILE)
 
 clean-test-config:
-       rm -f $(test_lib).config
+       rm -f Test/test-config-file-$(PROFILE)
 
 copy-targets: copy-targets-$(XBUILD_VERSION)
 
index ddd976ccd2089a79a4daff0e16ee01c7e1536714..7c3fb3d2c72fe03d751753e5f811c2793ae03e30 100644 (file)
@@ -51,6 +51,7 @@ set (
        btls-ssl-ctx.h
        btls-ssl.c
        btls-ssl.h
+       btls-time64.c
        btls-util.c
        btls-util.h
        btls-x509-chain.c
@@ -74,8 +75,6 @@ set (
        btls-x509.c
        btls-x509.h
 
-       btls-android-utils.c
-
        ${BORINGSSL_OBJECTS}
 )
 
index 4f640bead0b48af843e84f9bad5ec66905541d60..38f879c629fcf8dd79a18a199798bf8b3ef9ea7c 100644 (file)
@@ -1,4 +1,4 @@
-EXTRA_DIST = btls-android-utils.c \
+EXTRA_DIST = \
        btls-bio.c \
        btls-bio.h \
        btls-error.c \
@@ -11,6 +11,7 @@ EXTRA_DIST = btls-android-utils.c \
        btls-ssl-ctx.c \
        btls-ssl-ctx.h \
        btls-ssl.h \
+       btls-time64.c \
        btls-util.c \
        btls-util.h \
        btls-x509.c \
@@ -61,4 +62,5 @@ clean-local:
        -rm -rf build-shared
 
 install-exec-local:
-       $(install_sh) build-shared/libmono-btls-shared.* "$(DESTDIR)/$(libdir)"
+       $(mkinstalldirs) "$(DESTDIR)$(libdir)"
+       $(install_sh) build-shared/libmono-btls-shared.* "$(DESTDIR)$(libdir)"
diff --git a/mono/btls/btls-android-utils.c b/mono/btls/btls-android-utils.c
deleted file mode 100644 (file)
index df30f85..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copied from Chromium: https://src.chromium.org/svn/trunk/src/base/os_compat_android.cc
-
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#if defined(__ANDROID__)
-
-#include <asm/unistd.h>
-#include <errno.h>
-#include <math.h>
-#include <sys/stat.h>
-#include <sys/syscall.h>
-
-#if !defined(__LP64__)
-#include <time64.h>
-#endif
-
-#if !defined(__LP64__)
-// 32-bit Android has only timegm64() and not timegm().
-// We replicate the behaviour of timegm() when the result overflows time_t.
-time_t timegm(struct tm* const t) {
-  // time_t is signed on Android.
-  static const time_t kTimeMax = ~(1L << (sizeof(time_t) * CHAR_BIT - 1));
-  static const time_t kTimeMin = (1L << (sizeof(time_t) * CHAR_BIT - 1));
-  time64_t result = timegm64(t);
-  if (result < kTimeMin || result > kTimeMax)
-    return -1;
-  return result;
-}
-#endif
-
-#endif
index ea8fda67dc35096689e0e580561e7e4b68b38577..a35582a3b57f32e50bc759d8eaaaef7117fe6733 100644 (file)
@@ -64,8 +64,8 @@ mono_write (BIO *bio, const char *in, int inl)
        return mono->write_func (mono->instance, in, inl);
 }
 
-static long
-mono_ctrl (BIO *bio, int cmd, long num, void *ptr)
+static int64_t
+mono_ctrl (BIO *bio, int cmd, int64_t num, void *ptr)
 {
        MonoBtlsBio *mono = (MonoBtlsBio *)bio->ptr;
 
index d4429f6d6289d49bb7454e3bb9ae3b82237051ab..0795ef0f2ba1918be0ddf2ae9e8d40c11493fe07 100644 (file)
@@ -18,7 +18,7 @@ typedef enum {
 
 typedef int (* MonoBtlsReadFunc) (const void *instance, const void *buf, int size, int *wantMore);
 typedef int (* MonoBtlsWriteFunc) (const void *instance, const void *buf, int size);
-typedef long (* MonoBtlsControlFunc) (const void *instance, MonoBtlsControlCommand command, long arg);
+typedef int64_t (* MonoBtlsControlFunc) (const void *instance, MonoBtlsControlCommand command, int64_t arg);
 
 BIO *
 mono_btls_bio_mono_new (void);
diff --git a/mono/btls/btls-time64.c b/mono/btls/btls-time64.c
new file mode 100644 (file)
index 0000000..f01e8c0
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+
+Copyright (c) 2007-2008  Michael G Schwern
+
+This software originally derived from Paul Sheer's pivotal_gmtime_r.c.
+
+The MIT License:
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+
+/* See http://code.google.com/p/y2038 for this code's origin */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+
+/* Spec says except for stftime() and the _r() functions, these
+   all return static memory.  Stabbings! */
+static struct tm   Static_Return_Date;
+static char        Static_Return_String[35];
+
+static const int days_in_month[2][12] = {
+    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+    {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+};
+
+static const int julian_days_by_month[2][12] = {
+    {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
+    {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335},
+};
+
+static char const wday_name[7][3] = {
+    "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+};
+
+static char const mon_name[12][3] = {
+    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+static const int length_of_year[2] = { 365, 366 };
+
+/* Some numbers relating to the gregorian cycle */
+static const int64_t     years_in_gregorian_cycle   = 400;
+#define               days_in_gregorian_cycle      ((365 * 400) + 100 - 4 + 1)
+static const int64_t seconds_in_gregorian_cycle = days_in_gregorian_cycle * 60LL * 60LL * 24LL;
+
+/* Year range we can trust the time funcitons with */
+#define MAX_SAFE_YEAR 2037
+#define MIN_SAFE_YEAR 1971
+
+/* 28 year Julian calendar cycle */
+#define SOLAR_CYCLE_LENGTH 28
+
+/* Year cycle from MAX_SAFE_YEAR down. */
+static const int safe_years_high[SOLAR_CYCLE_LENGTH] = {
+    2016, 2017, 2018, 2019,
+    2020, 2021, 2022, 2023,
+    2024, 2025, 2026, 2027,
+    2028, 2029, 2030, 2031,
+    2032, 2033, 2034, 2035,
+    2036, 2037, 2010, 2011,
+    2012, 2013, 2014, 2015
+};
+
+/* Year cycle from MIN_SAFE_YEAR up */
+static const int safe_years_low[SOLAR_CYCLE_LENGTH] = {
+    1996, 1997, 1998, 1971,
+    1972, 1973, 1974, 1975,
+    1976, 1977, 1978, 1979,
+    1980, 1981, 1982, 1983,
+    1984, 1985, 1986, 1987,
+    1988, 1989, 1990, 1991,
+    1992, 1993, 1994, 1995,
+};
+
+/* Let's assume people are going to be looking for dates in the future.
+   Let's provide some cheats so you can skip ahead.
+   This has a 4x speed boost when near 2008.
+*/
+/* Number of days since epoch on Jan 1st, 2008 GMT */
+#define CHEAT_DAYS  (1199145600 / 24 / 60 / 60)
+#define CHEAT_YEARS 108
+
+#define IS_LEAP(n)      ((!(((n) + 1900) % 400) || (!(((n) + 1900) % 4) && (((n) + 1900) % 100))) != 0)
+#define WRAP(a,b,m)     ((a) = ((a) <  0  ) ? ((b)--, (a) + (m)) : (a))
+
+/* timegm() is not in the C or POSIX spec, but it is such a useful
+   extension I would be remiss in leaving it out.  Also I need it
+   for localtime64()
+*/
+int64_t btls_timegm64(const struct tm *date) {
+    int64_t days    = 0;
+    int64_t seconds = 0;
+    int64_t     year;
+    int64_t     orig_year = (int64_t)date->tm_year;
+    int      cycles  = 0;
+
+    if( orig_year > 100 ) {
+        cycles = (orig_year - 100) / 400;
+        orig_year -= cycles * 400;
+        days      += (int64_t)cycles * days_in_gregorian_cycle;
+    }
+    else if( orig_year < -300 ) {
+        cycles = (orig_year - 100) / 400;
+        orig_year -= cycles * 400;
+        days      += (int64_t)cycles * days_in_gregorian_cycle;
+    }
+
+    if( orig_year > 70 ) {
+        year = 70;
+        while( year < orig_year ) {
+            days += length_of_year[IS_LEAP(year)];
+            year++;
+        }
+    }
+    else if ( orig_year < 70 ) {
+        year = 69;
+        do {
+            days -= length_of_year[IS_LEAP(year)];
+            year--;
+        } while( year >= orig_year );
+    }
+
+
+    days += julian_days_by_month[IS_LEAP(orig_year)][date->tm_mon];
+    days += date->tm_mday - 1;
+
+    seconds = days * 60 * 60 * 24;
+
+    seconds += date->tm_hour * 60 * 60;
+    seconds += date->tm_min * 60;
+    seconds += date->tm_sec;
+
+    return(seconds);
+}
index 824b101f34c50ed68b88fd0e804a050ed7add745..7c7f4ca5b41a511496b431425788a3531f425749 100644 (file)
@@ -8,32 +8,33 @@
 
 #include <btls-util.h>
 #include <assert.h>
-#include <time.h>
-
-#if defined(__ANDROID__) && !defined(__LP64__)
-#include <time64.h>
-extern time_t timegm (struct tm* const t);
-#endif
+// #include <time.h>
 
 extern int asn1_generalizedtime_to_tm (struct tm *tm, const ASN1_GENERALIZEDTIME *d);
 
+extern int64_t btls_timegm64 (const struct tm *date);
+
+
 MONO_API void
 mono_btls_free (void *data)
 {
        OPENSSL_free (data);
 }
 
-long
+int64_t
 mono_btls_util_asn1_time_to_ticks (ASN1_TIME *time)
 {
        ASN1_GENERALIZEDTIME *gtime;
        struct tm tm;
-       time_t epoch;
+       int64_t epoch;
+       int ret;
+       
+       memset (&tm, 0, sizeof (tm));
 
        gtime = ASN1_TIME_to_generalizedtime (time, NULL);
-       asn1_generalizedtime_to_tm (&tm, gtime);
+       ret = asn1_generalizedtime_to_tm (&tm, gtime);
        ASN1_GENERALIZEDTIME_free (gtime);
-       epoch = timegm(&tm);
+       epoch = btls_timegm64 (&tm);
 
        return epoch;
 }
index 525e619975075b353cf87ca15b5669e87cb2f06a..a1b165235bd50eca05375db37681b9558f3dc89a 100644 (file)
@@ -33,7 +33,7 @@
 void
 mono_btls_free (void *data);
 
-long
+int64_t
 mono_btls_util_asn1_time_to_ticks (ASN1_TIME *time);
 
 int
index b4e861234cac0ed758b794fd3089de0f08689056..d496c072f1270b477ef6590b60e263746c6ab5b5 100644 (file)
@@ -124,19 +124,19 @@ mono_btls_x509_crl_get_revoked (MonoBtlsX509Crl *crl, int index)
        return mono_btls_x509_revoked_new (crl, revoked);
 }
 
-MONO_API long
+MONO_API int64_t
 mono_btls_x509_crl_get_last_update (MonoBtlsX509Crl *crl)
 {
        return mono_btls_util_asn1_time_to_ticks (X509_CRL_get_lastUpdate (crl->crl));
 }
 
-MONO_API long
+MONO_API int64_t
 mono_btls_x509_crl_get_next_update (MonoBtlsX509Crl *crl)
 {
        return mono_btls_util_asn1_time_to_ticks (X509_CRL_get_nextUpdate (crl->crl));
 }
 
-MONO_API long
+MONO_API int64_t
 mono_btls_x509_crl_get_version (MonoBtlsX509Crl *crl)
 {
        return X509_CRL_get_version (crl->crl);
index 0813fe5436adc0e8b59af330aed0fc1b69815fe0..625037d99a2ab747cb57725807246be32192f40d 100644 (file)
@@ -34,13 +34,13 @@ mono_btls_x509_crl_get_revoked_count (MonoBtlsX509Crl *crl);
 MonoBtlsX509Revoked *
 mono_btls_x509_crl_get_revoked (MonoBtlsX509Crl *crl, int index);
 
-long
+int64_t
 mono_btls_x509_crl_get_last_update (MonoBtlsX509Crl *crl);
 
-long
+int64_t
 mono_btls_x509_crl_get_next_update (MonoBtlsX509Crl *crl);
 
-long
+int64_t
 mono_btls_x509_crl_get_version (MonoBtlsX509Crl *crl);
 
 MonoBtlsX509Name *
index 1d8f7d3ee51f081d4674000fc9160995939a80c3..6d9d69a16f0670c2006e37e5d641a08b4efcdbfa 100644 (file)
@@ -103,7 +103,7 @@ mono_btls_x509_lookup_mono_free (MonoBtlsX509LookupMono *mono)
 }
 
 static int
-mono_lookup_ctrl (X509_LOOKUP *ctx, int cmd, const char *argp, long argl, char **ret)
+mono_lookup_ctrl (X509_LOOKUP *ctx, int cmd, const char *argp, int64_t argl, char **ret)
 {
        MonoLookup *lookup = (MonoLookup*)ctx->method_data;
        MonoBtlsX509LookupMono *mono = (MonoBtlsX509LookupMono*)argp;
index 782743f875259bfe50b4c4d3a8a6e91ea36d2f19..7f9875880026f712fcf673f1e58c74408472a8de 100644 (file)
@@ -153,13 +153,13 @@ mono_btls_x509_name_print_string (MonoBtlsX509Name *name, char *buffer, int size
        return X509_NAME_oneline (name->name, buffer, size) != NULL;
 }
 
-MONO_API long
+MONO_API int64_t
 mono_btls_x509_name_hash (MonoBtlsX509Name *name)
 {
        return X509_NAME_hash (name->name);
 }
 
-MONO_API long
+MONO_API int64_t
 mono_btls_x509_name_hash_old (MonoBtlsX509Name *name)
 {
        return X509_NAME_hash_old (name->name);
index 604de2bb5e6627a682debcd033b3c4bb23420cd3..9d43bc6499158cda4ba795b5691aa2be2ed96320 100644 (file)
@@ -56,10 +56,10 @@ mono_btls_x509_name_print_string (MonoBtlsX509Name *name, char *buffer, int size
 int
 mono_btls_x509_name_get_raw_data (MonoBtlsX509Name *name, void **buffer, int use_canon_enc);
 
-long
+int64_t
 mono_btls_x509_name_hash (MonoBtlsX509Name *name);
 
-long
+int64_t
 mono_btls_x509_name_hash_old (MonoBtlsX509Name *name);
 
 int
index d0540e6ca10f872f868719aee9007e493739a325..bf9af79de46920f7964e2b2032bb30f39177a2b7 100644 (file)
@@ -46,7 +46,7 @@ mono_btls_x509_revoked_get_serial_number (MonoBtlsX509Revoked *revoked, char *bu
        return serial->length;
 }
 
-MONO_API long
+MONO_API int64_t
 mono_btls_x509_revoked_get_revocation_date (MonoBtlsX509Revoked *revoked)
 {
        ASN1_TIME *date;
index e1229c6a47f211f17e0eb9744438d120c4be703b..592fc9316a1bc534a28a815c956f5682e5af1a3e 100644 (file)
@@ -22,7 +22,7 @@ mono_btls_x509_revoked_free (MonoBtlsX509Revoked *revoked);
 int
 mono_btls_x509_revoked_get_serial_number (MonoBtlsX509Revoked *revoked, char *buffer, int size);
 
-long
+int64_t
 mono_btls_x509_revoked_get_revocation_date (MonoBtlsX509Revoked *revoked);
 
 int
index 5ac8bdbb099c574de77c2cef4c7831829a107271..24be3da8ca11acb6805686730210ff3b36cde3f8 100644 (file)
@@ -126,14 +126,14 @@ mono_btls_x509_verify_param_add_host (MonoBtlsX509VerifyParam *param, const char
        return X509_VERIFY_PARAM_set1_host (param->param, host, namelen);
 }
 
-MONO_API unsigned long
+MONO_API uint64_t
 mono_btls_x509_verify_param_get_flags (MonoBtlsX509VerifyParam *param)
 {
        return X509_VERIFY_PARAM_get_flags (param->param);
 }
 
 MONO_API int
-mono_btls_x509_verify_param_set_flags (MonoBtlsX509VerifyParam *param, unsigned long flags)
+mono_btls_x509_verify_param_set_flags (MonoBtlsX509VerifyParam *param, uint64_t flags)
 {
        if (!param->owns)
                return -1;
@@ -144,7 +144,7 @@ MONO_API MonoBtlsX509VerifyFlags
 mono_btls_x509_verify_param_get_mono_flags (MonoBtlsX509VerifyParam *param)
 {
        MonoBtlsX509VerifyFlags current;
-       unsigned long flags;
+       uint64_t flags;
 
        if (!param->owns)
                return -1;
@@ -165,7 +165,7 @@ mono_btls_x509_verify_param_get_mono_flags (MonoBtlsX509VerifyParam *param)
 MONO_API int
 mono_btls_x509_verify_param_set_mono_flags (MonoBtlsX509VerifyParam *param, MonoBtlsX509VerifyFlags flags)
 {
-       unsigned long current;
+       uint64_t current;
 
        if (!param->owns)
                return -1;
@@ -205,7 +205,7 @@ mono_btls_x509_verify_param_set_depth (MonoBtlsX509VerifyParam *param, int depth
 }
 
 MONO_API int
-mono_btls_x509_verify_param_set_time (MonoBtlsX509VerifyParam *param, long time)
+mono_btls_x509_verify_param_set_time (MonoBtlsX509VerifyParam *param, int64_t time)
 {
        if (!param->owns)
                return -1;
index 6f4f1b51a8e71c3d34440cbd44b858aedcd30db5..e85d547fb3e68ec37268024e08734ebb7a8de216 100644 (file)
@@ -50,11 +50,11 @@ mono_btls_x509_verify_param_set_host (MonoBtlsX509VerifyParam *param, const char
 int
 mono_btls_x509_verify_param_add_host (MonoBtlsX509VerifyParam *param, const char *host, int namelen);
 
-unsigned long
+uint64_t
 mono_btls_x509_verify_param_get_flags (MonoBtlsX509VerifyParam *param);
 
 int
-mono_btls_x509_verify_param_set_flags (MonoBtlsX509VerifyParam *param, unsigned long flags);
+mono_btls_x509_verify_param_set_flags (MonoBtlsX509VerifyParam *param, uint64_t flags);
 
 MonoBtlsX509VerifyFlags
 mono_btls_x509_verify_param_get_mono_flags (MonoBtlsX509VerifyParam *param);
@@ -72,7 +72,7 @@ int
 mono_btls_x509_verify_param_set_depth (MonoBtlsX509VerifyParam *param, int depth);
 
 int
-mono_btls_x509_verify_param_set_time (MonoBtlsX509VerifyParam *param, long time);
+mono_btls_x509_verify_param_set_time (MonoBtlsX509VerifyParam *param, int64_t time);
 
 char *
 mono_btls_x509_verify_param_get_peername (MonoBtlsX509VerifyParam *param);
index ae75f3ce9128b95cb9d53d34b7292a84b06b1e15..473d94fbaf3e341d0d7851860952bf6de7216bc8 100644 (file)
@@ -101,13 +101,13 @@ mono_btls_x509_get_hash (X509 *x509, const void **data)
        return SHA_DIGEST_LENGTH;
 }
 
-MONO_API long
+MONO_API int64_t
 mono_btls_x509_get_not_before (X509 *x509)
 {
        return mono_btls_util_asn1_time_to_ticks (X509_get_notBefore (x509));
 }
 
-MONO_API long
+MONO_API int64_t
 mono_btls_x509_get_not_after (X509 *x509)
 {
        return mono_btls_util_asn1_time_to_ticks (X509_get_notAfter (x509));
index a9a9200127d47ee4b011e85908e7f8fd60132036..d9137431333d46cca5ffbf7f9f25ce25a456300c 100644 (file)
@@ -79,10 +79,10 @@ mono_btls_x509_cmp (const X509 *a, const X509 *b);
 int
 mono_btls_x509_get_hash (X509 *x509, const void **data);
 
-long
+int64_t
 mono_btls_x509_get_not_before (X509 *x509);
 
-long
+int64_t
 mono_btls_x509_get_not_after (X509 *x509);
 
 int
index f3724e4384debca76a5eae810a91e4dc8333e278..ca9c92e0ae60cdb0a808a654ade306a8d2565c70 100755 (executable)
@@ -1103,8 +1103,8 @@ dis_stringify_object_with_class (MonoImage *m, MonoClass *c, gboolean prefix, gb
 
        esname = get_escaped_class_name (c);
 
-       if (c->generic_class) {
-               MonoGenericClass *gclass = c->generic_class;
+       if (mono_class_is_ginst (c)) {
+               MonoGenericClass *gclass = mono_class_get_generic_class (c);
                MonoGenericInst *inst = gclass->context.class_inst;
                GString *str = g_string_new ("");
                int i;
@@ -1847,7 +1847,7 @@ get_memberref_container (MonoImage *m, guint32 mrp_token, MonoGenericContainer *
        case 4: /* TypeSpec */
                klass = mono_class_get_full (m, MONO_TOKEN_TYPE_SPEC | idx, (MonoGenericContext *) container);
                g_assert (klass);
-               return klass->generic_class ? klass->generic_class->container_class->generic_container : NULL;
+               return mono_class_is_ginst (klass) ? mono_class_get_generic_container (mono_class_get_generic_class (klass)->container_class) : NULL;
        }
        g_assert_not_reached ();
        return NULL;
@@ -3108,7 +3108,7 @@ get_method_override (MonoImage *m, guint32 token, MonoGenericContainer *containe
                        MonoMethod *mh = NULL;
                        mh = mono_get_method_checked (m, decl, NULL, (MonoGenericContext *) container, &error);
 
-                       if (mh && (mh->klass && (mh->klass->generic_class || mh->klass->generic_container))) {
+                       if (mh && (mh->klass && (mono_class_is_ginst (mh->klass) || mono_class_is_gtd (mh->klass)))) {
                                char *meth_str;
                                char *ret;
                                
index dfb60a16c827e5db876948193eef80196708b887..dae93fe23a49718c0980ed4707937be3bf8160f2 100644 (file)
@@ -11,7 +11,6 @@ AM_CPPFLAGS = \
 libwapiincludedir = $(includedir)/mono-$(API_VER)/mono/io-layer
 
 OTHER_H = \
-       access.h        \
        context.h       \
        error.h         \
        io.h            \
@@ -20,7 +19,6 @@ OTHER_H = \
        io-portability.h        \
        macros.h        \
        messages.h      \
-       processes.h     \
        security.h      \
        sockets.h       \
        status.h        \
@@ -33,7 +31,6 @@ OTHER_H = \
        wapi-remap.h
 
 OTHER_SRC = \
-       access.h                \
        context.c               \
        context.h               \
        error.c                 \
@@ -49,9 +46,6 @@ OTHER_SRC = \
        messages.c              \
        messages.h              \
        posix.c                 \
-       processes.c             \
-       processes.h             \
-       process-private.h       \
        security.c              \
        security.h              \
        sockets.c               \
@@ -61,7 +55,6 @@ OTHER_SRC = \
        status.h                \
        timefuncs.c             \
        timefuncs.h             \
-       timefuncs-private.h     \
        types.h                 \
        uglify.h                \
        versioninfo.c           \
diff --git a/mono/io-layer/access.h b/mono/io-layer/access.h
deleted file mode 100644 (file)
index 2cb48b3..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * access.h:  Access control definitions
- *
- * Author:
- *     Dick Porter (dick@ximian.com)
- *
- * (C) 2002 Ximian, Inc.
- */
-
-#ifndef _WAPI_ACCESS_H_
-#define _WAPI_ACCESS_H_
-
-#include <glib.h>
-
-#include <mono/io-layer/wapi.h>
-
-#define SYNCHRONIZE                    0x00100000
-#define STANDARD_RIGHTS_REQUIRED       0x000f0000
-
-#endif /* _WAPI_ACCESS_H_ */
index db128be5c72a6c3948f3056f915c02284e5461ca..bc884c3d8d9f14f8f97385b51ff70fae3f3bc713 100644 (file)
 
 #include "mono/io-layer/wapi.h"
 #include "mono/io-layer/wapi-private.h"
-#include "mono/utils/mono-once.h"
+#include "mono/utils/mono-lazy-init.h"
 
 static pthread_key_t error_key;
-static mono_once_t error_key_once=MONO_ONCE_INIT;
+static mono_lazy_init_t error_key_once = MONO_LAZY_INIT_STATUS_NOT_INITIALIZED;
 
 static void error_init(void)
 {
@@ -28,7 +28,7 @@ static void error_init(void)
        g_assert (ret == 0);
 }
 
-void _wapi_error_cleanup (void)
+static void error_cleanup (void)
 {
        int ret;
 
@@ -36,6 +36,11 @@ void _wapi_error_cleanup (void)
        g_assert (ret == 0);
 }
 
+void _wapi_error_cleanup (void)
+{
+       mono_lazy_cleanup (&error_key_once, error_cleanup);
+}
+
 /**
  * GetLastError:
  *
@@ -51,7 +56,7 @@ guint32 GetLastError(void)
 
        if (_wapi_has_shut_down)
                return 0;
-       mono_once(&error_key_once, error_init);
+       mono_lazy_initialize(&error_key_once, error_init);
        errptr=pthread_getspecific(error_key);
        err=GPOINTER_TO_UINT(errptr);
        
@@ -71,7 +76,7 @@ void SetLastError(guint32 code)
        if (_wapi_has_shut_down)
                return;
        /* Set the thread-local error code */
-       mono_once(&error_key_once, error_init);
+       mono_lazy_initialize(&error_key_once, error_init);
        ret = pthread_setspecific(error_key, GUINT_TO_POINTER(code));
        g_assert (ret == 0);
 }
index 661067dc7b27b1461c9ee63858da5c519e0256f2..3106fc13078bbd75f986b6eb143eb92d91197a95 100644 (file)
 #include <mono/io-layer/wapi.h>
 #include <mono/io-layer/wapi-private.h>
 #include <mono/io-layer/io-private.h>
-#include <mono/io-layer/timefuncs-private.h>
+#include <mono/io-layer/timefuncs.h>
 #include <mono/io-layer/io-portability.h>
 #include <mono/io-layer/io-trace.h>
 #include <mono/utils/strenc.h>
 #include <mono/utils/mono-once.h>
 #include <mono/utils/mono-logger-internals.h>
-#include <mono/utils/w32handle.h>
+#include <mono/metadata/w32handle.h>
 
 /*
  * If SHM is disabled, this will point to a hash of _WapiFileShare structures, otherwise
index 001df9bef7e9273d726f2999880915377f1cb9ef..86eb864365f043d173bf1e344414a56610491cdd 100644 (file)
@@ -18,7 +18,7 @@
 #include <mono/io-layer/io-private.h>
 #include <mono/io-layer/io-trace.h>
 #include <mono/utils/mono-logger-internals.h>
-#include <mono/utils/w32handle.h>
+#include <mono/metadata/w32handle.h>
 
 gboolean
 _wapi_lock_file_region (int fd, off_t offset, off_t length)
index fe350c8b8660e59da13d8a2646a62f49db2fb2d9..995795bb32614fa12c11936e497f01991ef1c231 100644 (file)
@@ -25,7 +25,7 @@
 #include <mono/io-layer/io-private.h>
 #include <mono/io-layer/io-trace.h>
 #include <mono/utils/mono-logger-internals.h>
-#include <mono/utils/w32handle.h>
+#include <mono/metadata/w32handle.h>
 
 static guint32
 convert_from_flags(int flags)
diff --git a/mono/io-layer/process-private.h b/mono/io-layer/process-private.h
deleted file mode 100644 (file)
index a17de8a..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * process-private.h: Private definitions for process handles
- *
- * Author:
- *     Dick Porter (dick@ximian.com)
- *
- * (C) 2002-2006 Novell, Inc.
- */
-
-#ifndef _WAPI_PROCESS_PRIVATE_H_
-#define _WAPI_PROCESS_PRIVATE_H_
-
-#include <config.h>
-#include <glib.h>
-
-#include <mono/utils/mono-os-semaphore.h>
-
-/* There doesn't seem to be a defined symbol for this */
-#define _WAPI_PROCESS_CURRENT (gpointer)0xFFFFFFFF
-
-/*
- * Handles > _WAPI_PROCESS_UNHANDLED are pseudo handles which represent processes
- * not started by the runtime.
- */
-/* This marks a system process that we don't have a handle on */
-/* FIXME: Cope with PIDs > sizeof guint */
-#define _WAPI_PROCESS_UNHANDLED (1 << (8*sizeof(pid_t)-1))
-#define _WAPI_PROCESS_UNHANDLED_PID_MASK (-1 & ~_WAPI_PROCESS_UNHANDLED)
-#define WAPI_IS_PSEUDO_PROCESS_HANDLE(handle) ((GPOINTER_TO_UINT(handle) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED)
-#define WAPI_PID_TO_HANDLE(pid) GINT_TO_POINTER (_WAPI_PROCESS_UNHANDLED + (pid))
-#define WAPI_HANDLE_TO_PID(handle) (GPOINTER_TO_UINT ((handle)) - _WAPI_PROCESS_UNHANDLED)
-
-void _wapi_processes_init (void);
-extern gpointer _wapi_process_duplicate (void);
-extern void wapi_processes_cleanup (void);
-
-/*
- * MonoProcess describes processes we create.
- * It contains a semaphore that can be waited on in order to wait
- * for process termination. It's accessed in our SIGCHLD handler,
- * when status is updated (and pid cleared, to not clash with 
- * subsequent processes that may get executed).
- */
-struct MonoProcess {
-       pid_t pid; /* the pid of the process. This value is only valid until the process has exited. */
-       MonoSemType exit_sem; /* this semaphore will be released when the process exits */
-       int status; /* the exit status */
-       gint32 handle_count; /* the number of handles to this mono_process instance */
-       /* we keep a ref to the creating _WapiHandle_process handle until
-        * the process has exited, so that the information there isn't lost.
-        */
-       gpointer handle;
-       gboolean freeable;
-       struct MonoProcess *next;
-};
-
-typedef struct MonoProcess MonoProcess;
-
-/*
- * _WapiHandle_process is a structure containing all the required information
- * for process handling.
- */
-struct _WapiHandle_process
-{
-       pid_t id;
-       guint32 exitstatus;
-       gpointer main_thread;
-       WapiFileTime create_time;
-       WapiFileTime exit_time;
-       char *proc_name;
-       size_t min_working_set;
-       size_t max_working_set;
-       gboolean exited;
-       struct MonoProcess *mono_process;
-};
-
-typedef struct _WapiHandle_process WapiHandle_process;
-
-#endif /* _WAPI_PROCESS_PRIVATE_H_ */
diff --git a/mono/io-layer/processes.c b/mono/io-layer/processes.c
deleted file mode 100644 (file)
index fd55cd7..0000000
+++ /dev/null
@@ -1,2880 +0,0 @@
-/*
- * processes.c:  Process handles
- *
- * Author:
- *     Dick Porter (dick@ximian.com)
- *
- * (C) 2002-2011 Novell, Inc.
- * Copyright 2011 Xamarin Inc
- * Licensed under the MIT license. See LICENSE file in the project root for full license information.
- */
-
-#include <config.h>
-#include <glib.h>
-#include <stdio.h>
-#include <string.h>
-#include <pthread.h>
-#include <sched.h>
-#include <sys/time.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#ifdef HAVE_SIGNAL_H
-#include <signal.h>
-#endif
-#include <sys/time.h>
-#include <fcntl.h>
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-#include <ctype.h>
-
-#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>
-#endif
-#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/resource.h>
-#endif
-
-#ifdef HAVE_SYS_MKDEV_H
-#include <sys/mkdev.h>
-#endif
-
-#ifdef HAVE_UTIME_H
-#include <utime.h>
-#endif
-
-/* sys/resource.h (for rusage) is required when using osx 10.3 (but not 10.4) */
-#ifdef __APPLE__
-#include <TargetConditionals.h>
-#include <sys/resource.h>
-#ifdef HAVE_LIBPROC_H
-/* proc_name */
-#include <libproc.h>
-#endif
-#endif
-
-#if defined(PLATFORM_MACOSX)
-#define USE_OSX_LOADER
-#endif
-
-#if ( defined(__OpenBSD__) || defined(__FreeBSD__) ) && defined(HAVE_LINK_H)
-#define USE_BSD_LOADER
-#endif
-
-#if defined(__HAIKU__)
-#define USE_HAIKU_LOADER
-#endif
-
-#if defined(USE_OSX_LOADER) || defined(USE_BSD_LOADER)
-#include <sys/proc.h>
-#include <sys/sysctl.h>
-#  if !defined(__OpenBSD__)
-#    include <sys/utsname.h>
-#  endif
-#  if defined(__FreeBSD__)
-#    include <sys/user.h>  /* struct kinfo_proc */
-#  endif
-#endif
-
-#ifdef PLATFORM_SOLARIS
-/* procfs.h cannot be included if this define is set, but it seems to work fine if it is undefined */
-#if _FILE_OFFSET_BITS == 64
-#undef _FILE_OFFSET_BITS
-#include <procfs.h>
-#define _FILE_OFFSET_BITS 64
-#else
-#include <procfs.h>
-#endif
-#endif
-
-#ifdef __HAIKU__
-#include <KernelKit.h>
-#endif
-
-#include <mono/io-layer/wapi.h>
-#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/process-private.h>
-#include <mono/io-layer/io-trace.h>
-#include <mono/utils/strenc.h>
-#include <mono/utils/mono-path.h>
-#include <mono/io-layer/timefuncs-private.h>
-#include <mono/utils/mono-time.h>
-#include <mono/utils/mono-membar.h>
-#include <mono/utils/mono-os-mutex.h>
-#include <mono/utils/mono-signal-handler.h>
-#include <mono/utils/mono-proclib.h>
-#include <mono/utils/mono-once.h>
-#include <mono/utils/mono-logger-internals.h>
-#include <mono/utils/w32handle.h>
-
-#define STILL_ACTIVE STATUS_PENDING
-
-/* The process' environment strings */
-#if defined(__APPLE__)
-#if defined (TARGET_OSX)
-/* Apple defines this in crt_externs.h but doesn't provide that header for 
- * arm-apple-darwin9.  We'll manually define the symbol on Apple as it does
- * in fact exist on all implementations (so far) 
- */
-gchar ***_NSGetEnviron(void);
-#define environ (*_NSGetEnviron())
-#else
-static char *mono_environ[1] = { NULL };
-#define environ mono_environ
-#endif /* defined (TARGET_OSX) */
-#else
-extern char **environ;
-#endif
-
-static guint32 process_wait (gpointer handle, guint32 timeout, gboolean *alerted);
-static void process_close (gpointer handle, gpointer data);
-static void process_details (gpointer data);
-static const gchar* process_typename (void);
-static gsize process_typesize (void);
-static gboolean is_pid_valid (pid_t pid);
-
-#if !(defined(USE_OSX_LOADER) || defined(USE_BSD_LOADER) || defined(USE_HAIKU_LOADER))
-static FILE *
-open_process_map (int pid, const char *mode);
-#endif
-
-static MonoW32HandleOps _wapi_process_ops = {
-       process_close,          /* close_shared */
-       NULL,                           /* signal */
-       NULL,                           /* own */
-       NULL,                           /* is_owned */
-       process_wait,                   /* special_wait */
-       NULL,                           /* prewait */
-       process_details,        /* details */
-       process_typename,       /* typename */
-       process_typesize,       /* typesize */
-};
-
-#if HAVE_SIGACTION
-static struct sigaction previous_chld_sa;
-#endif
-static mono_once_t process_sig_chld_once = MONO_ONCE_INIT;
-static void process_add_sigchld_handler (void);
-
-/* The signal-safe logic to use mono_processes goes like this:
- * - The list must be safe to traverse for the signal handler at all times.
- *   It's safe to: prepend an entry (which is a single store to 'mono_processes'),
- *   unlink an entry (assuming the unlinked entry isn't freed and doesn't 
- *   change its 'next' pointer so that it can still be traversed).
- * When cleaning up we first unlink an entry, then we verify that
- * the read lock isn't locked. Then we can free the entry, since
- * we know that nobody is using the old version of the list (including
- * the unlinked entry).
- * We also need to lock when adding and cleaning up so that those two
- * operations don't mess with eachother. (This lock is not used in the
- * signal handler)
- */
-static struct MonoProcess *mono_processes = NULL;
-static volatile gint32 mono_processes_cleaning_up = 0;
-static mono_mutex_t mono_processes_mutex;
-static void mono_processes_cleanup (void);
-
-static gpointer current_process;
-static char *cli_launcher;
-
-static WapiHandle_process *
-lookup_process_handle (gpointer handle)
-{
-       WapiHandle_process *process_data;
-       gboolean ret;
-
-       ret = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS,
-                                                          (gpointer *)&process_data);
-       if (!ret)
-               return NULL;
-       return process_data;
-}
-
-/* Check if a pid is valid - i.e. if a process exists with this pid. */
-static gboolean
-is_pid_valid (pid_t pid)
-{
-       gboolean result = FALSE;
-
-#if defined(HOST_WATCHOS)
-       result = TRUE; // TODO: Rewrite using sysctl
-#elif defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__FreeBSD__)
-       if (((kill(pid, 0) == 0) || (errno == EPERM)) && pid != 0)
-               result = TRUE;
-#elif defined(__HAIKU__)
-       team_info teamInfo;
-       if (get_team_info ((team_id)pid, &teamInfo) == B_OK)
-               result = TRUE;
-#else
-       char *dir = g_strdup_printf ("/proc/%d", pid);
-       if (!access (dir, F_OK))
-               result = TRUE;
-       g_free (dir);
-#endif
-       
-       return result;
-}
-
-static void
-process_set_defaults (WapiHandle_process *process_handle)
-{
-       /* These seem to be the defaults on w2k */
-       process_handle->min_working_set = 204800;
-       process_handle->max_working_set = 1413120;
-       
-       _wapi_time_t_to_filetime (time (NULL), &process_handle->create_time);
-}
-
-static int
-len16 (const gunichar2 *str)
-{
-       int len = 0;
-       
-       while (*str++ != 0)
-               len++;
-
-       return len;
-}
-
-static gunichar2 *
-utf16_concat (const gunichar2 *first, ...)
-{
-       va_list args;
-       int total = 0, i;
-       const gunichar2 *s;
-       gunichar2 *ret;
-
-       va_start (args, first);
-       total += len16 (first);
-        for (s = va_arg (args, gunichar2 *); s != NULL; s = va_arg(args, gunichar2 *)){
-               total += len16 (s);
-        }
-       va_end (args);
-
-       ret = g_new (gunichar2, total + 1);
-       if (ret == NULL)
-               return NULL;
-
-       ret [total] = 0;
-       i = 0;
-       for (s = first; *s != 0; s++)
-               ret [i++] = *s;
-       va_start (args, first);
-       for (s = va_arg (args, gunichar2 *); s != NULL; s = va_arg (args, gunichar2 *)){
-               const gunichar2 *p;
-               
-               for (p = s; *p != 0; p++)
-                       ret [i++] = *p;
-       }
-       va_end (args);
-       
-       return ret;
-}
-
-static const gunichar2 utf16_space_bytes [2] = { 0x20, 0 };
-static const gunichar2 *utf16_space = utf16_space_bytes; 
-static const gunichar2 utf16_quote_bytes [2] = { 0x22, 0 };
-static const gunichar2 *utf16_quote = utf16_quote_bytes;
-
-#ifdef DEBUG_ENABLED
-/* Useful in gdb */
-void
-print_utf16 (gunichar2 *str)
-{
-       char *res;
-
-       res = g_utf16_to_utf8 (str, -1, NULL, NULL, NULL);
-       g_print ("%s\n", res);
-       g_free (res);
-}
-#endif
-
-/* Implemented as just a wrapper around CreateProcess () */
-gboolean
-ShellExecuteEx (WapiShellExecuteInfo *sei)
-{
-       gboolean ret;
-       WapiProcessInformation process_info;
-       gunichar2 *args;
-       
-       if (sei == NULL) {
-               /* w2k just segfaults here, but we can do better than
-                * that
-                */
-               SetLastError (ERROR_INVALID_PARAMETER);
-               return FALSE;
-       }
-
-       if (sei->lpFile == NULL)
-               /* w2k returns TRUE for this, for some reason. */
-               return TRUE;
-       
-       /* Put both executable and parameters into the second argument
-        * to CreateProcess (), so it searches $PATH.  The conversion
-        * into and back out of utf8 is because there is no
-        * g_strdup_printf () equivalent for gunichar2 :-(
-        */
-       args = utf16_concat (utf16_quote, sei->lpFile, utf16_quote, sei->lpParameters == NULL ? NULL : utf16_space, sei->lpParameters, NULL);
-       if (args == NULL) {
-               SetLastError (ERROR_INVALID_DATA);
-               return FALSE;
-       }
-       ret = CreateProcess (NULL, args, NULL, NULL, TRUE,
-                            CREATE_UNICODE_ENVIRONMENT, NULL,
-                            sei->lpDirectory, NULL, &process_info);
-       g_free (args);
-
-       if (!ret && GetLastError () == ERROR_OUTOFMEMORY)
-               return ret;
-       
-       if (!ret) {
-               static char *handler;
-               static gunichar2 *handler_utf16;
-               
-               if (handler_utf16 == (gunichar2 *)-1)
-                       return FALSE;
-
-#ifdef PLATFORM_MACOSX
-               handler = g_strdup ("/usr/bin/open");
-#else
-               /*
-                * On Linux, try: xdg-open, the FreeDesktop standard way of doing it,
-                * if that fails, try to use gnome-open, then kfmclient
-                */
-               handler = g_find_program_in_path ("xdg-open");
-               if (handler == NULL){
-                       handler = g_find_program_in_path ("gnome-open");
-                       if (handler == NULL){
-                               handler = g_find_program_in_path ("kfmclient");
-                               if (handler == NULL){
-                                       handler_utf16 = (gunichar2 *) -1;
-                                       return FALSE;
-                               } else {
-                                       /* kfmclient needs exec argument */
-                                       char *old = handler;
-                                       handler = g_strconcat (old, " exec",
-                                                              NULL);
-                                       g_free (old);
-                               }
-                       }
-               }
-#endif
-               handler_utf16 = g_utf8_to_utf16 (handler, -1, NULL, NULL, NULL);
-               g_free (handler);
-
-               /* Put quotes around the filename, in case it's a url
-                * that contains #'s (CreateProcess() calls
-                * g_shell_parse_argv(), which deliberately throws
-                * away anything after an unquoted #).  Fixes bug
-                * 371567.
-                */
-               args = utf16_concat (handler_utf16, utf16_space, utf16_quote,
-                                    sei->lpFile, utf16_quote,
-                                    sei->lpParameters == NULL ? NULL : utf16_space,
-                                    sei->lpParameters, NULL);
-               if (args == NULL) {
-                       SetLastError (ERROR_INVALID_DATA);
-                       return FALSE;
-               }
-               ret = CreateProcess (NULL, args, NULL, NULL, TRUE,
-                                    CREATE_UNICODE_ENVIRONMENT, NULL,
-                                    sei->lpDirectory, NULL, &process_info);
-               g_free (args);
-               if (!ret) {
-                       if (GetLastError () != ERROR_OUTOFMEMORY)
-                               SetLastError (ERROR_INVALID_DATA);
-                       return FALSE;
-               }
-               /* Shell exec should not return a process handle when it spawned a GUI thing, like a browser. */
-               CloseHandle (process_info.hProcess);
-               process_info.hProcess = NULL;
-       }
-       
-       if (sei->fMask & SEE_MASK_NOCLOSEPROCESS)
-               sei->hProcess = process_info.hProcess;
-       else
-               CloseHandle (process_info.hProcess);
-       
-       return ret;
-}
-
-static gboolean
-is_managed_binary (const char *filename)
-{
-       int original_errno = errno;
-#if defined(HAVE_LARGE_FILE_SUPPORT) && defined(O_LARGEFILE)
-       int file = open (filename, O_RDONLY | O_LARGEFILE);
-#else
-       int file = open (filename, O_RDONLY);
-#endif
-       off_t new_offset;
-       unsigned char buffer[8];
-       off_t file_size, optional_header_offset;
-       off_t pe_header_offset, clr_header_offset;
-       gboolean managed = FALSE;
-       int num_read;
-       guint32 first_word, second_word, magic_number;
-       
-       /* If we are unable to open the file, then we definitely
-        * can't say that it is managed. The child mono process
-        * probably wouldn't be able to open it anyway.
-        */
-       if (file < 0) {
-               errno = original_errno;
-               return FALSE;
-       }
-
-       /* Retrieve the length of the file for future sanity checks. */
-       file_size = lseek (file, 0, SEEK_END);
-       lseek (file, 0, SEEK_SET);
-
-       /* We know we need to read a header field at offset 60. */
-       if (file_size < 64)
-               goto leave;
-
-       num_read = read (file, buffer, 2);
-
-       if ((num_read != 2) || (buffer[0] != 'M') || (buffer[1] != 'Z'))
-               goto leave;
-
-       new_offset = lseek (file, 60, SEEK_SET);
-
-       if (new_offset != 60)
-               goto leave;
-       
-       num_read = read (file, buffer, 4);
-
-       if (num_read != 4)
-               goto leave;
-       pe_header_offset =  buffer[0]
-               | (buffer[1] <<  8)
-               | (buffer[2] << 16)
-               | (buffer[3] << 24);
-       
-       if (pe_header_offset + 24 > file_size)
-               goto leave;
-
-       new_offset = lseek (file, pe_header_offset, SEEK_SET);
-
-       if (new_offset != pe_header_offset)
-               goto leave;
-
-       num_read = read (file, buffer, 4);
-
-       if ((num_read != 4) || (buffer[0] != 'P') || (buffer[1] != 'E') || (buffer[2] != 0) || (buffer[3] != 0))
-               goto leave;
-
-       /*
-        * Verify that the header we want in the optional header data
-        * is present in this binary.
-        */
-       new_offset = lseek (file, pe_header_offset + 20, SEEK_SET);
-
-       if (new_offset != pe_header_offset + 20)
-               goto leave;
-
-       num_read = read (file, buffer, 2);
-
-       if ((num_read != 2) || ((buffer[0] | (buffer[1] << 8)) < 216))
-               goto leave;
-
-       optional_header_offset = pe_header_offset + 24;
-
-       /* Read the PE magic number */
-       new_offset = lseek (file, optional_header_offset, SEEK_SET);
-       
-       if (new_offset != optional_header_offset)
-               goto leave;
-
-       num_read = read (file, buffer, 2);
-
-       if (num_read != 2)
-               goto leave;
-
-       magic_number = (buffer[0] | (buffer[1] << 8));
-       
-       if (magic_number == 0x10B)  // PE32
-               clr_header_offset = 208;
-       else if (magic_number == 0x20B)  // PE32+
-               clr_header_offset = 224;
-       else
-               goto leave;
-
-       /* Read the CLR header address and size fields. These will be
-        * zero if the binary is not managed.
-        */
-       new_offset = lseek (file, optional_header_offset + clr_header_offset, SEEK_SET);
-
-       if (new_offset != optional_header_offset + clr_header_offset)
-               goto leave;
-
-       num_read = read (file, buffer, 8);
-       
-       /* We are not concerned with endianness, only with
-        * whether it is zero or not.
-        */
-       first_word = *(guint32 *)&buffer[0];
-       second_word = *(guint32 *)&buffer[4];
-       
-       if ((num_read != 8) || (first_word == 0) || (second_word == 0))
-               goto leave;
-       
-       managed = TRUE;
-
-leave:
-       close (file);
-       errno = original_errno;
-       return managed;
-}
-
-gboolean
-CreateProcessWithLogonW (const gunichar2 *username,
-                                                const gunichar2 *domain,
-                                                const gunichar2 *password,
-                                                const guint32 logonFlags,
-                                                const gunichar2 *appname,
-                                                const gunichar2 *cmdline,
-                                                guint32 create_flags,
-                                                gpointer env,
-                                                const gunichar2 *cwd,
-                                                WapiStartupInfo *startup,
-                                                WapiProcessInformation *process_info)
-{
-       /* FIXME: use user information */
-       return CreateProcess (appname, cmdline, NULL, NULL, FALSE, create_flags, env, cwd, startup, process_info);
-}
-
-static gboolean
-is_readable_or_executable (const char *prog)
-{
-       struct stat buf;
-       int a = access (prog, R_OK);
-       int b = access (prog, X_OK);
-       if (a != 0 && b != 0)
-               return FALSE;
-       if (stat (prog, &buf))
-               return FALSE;
-       if (S_ISREG (buf.st_mode))
-               return TRUE;
-       return FALSE;
-}
-
-static gboolean
-is_executable (const char *prog)
-{
-       struct stat buf;
-       if (access (prog, X_OK) != 0)
-               return FALSE;
-       if (stat (prog, &buf))
-               return FALSE;
-       if (S_ISREG (buf.st_mode))
-               return TRUE;
-       return FALSE;
-}
-
-static void
-switch_dir_separators (char *path)
-{
-       size_t i, pathLength = strlen(path);
-       
-       /* Turn all the slashes round the right way, except for \' */
-       /* There are probably other characters that need to be excluded as well. */
-       for (i = 0; i < pathLength; i++) {
-               if (path[i] == '\\' && i < pathLength - 1 && path[i+1] != '\'' )
-                       path[i] = '/';
-       }
-}
-
-gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline,
-                       WapiSecurityAttributes *process_attrs G_GNUC_UNUSED,
-                       WapiSecurityAttributes *thread_attrs G_GNUC_UNUSED,
-                       gboolean inherit_handles, guint32 create_flags,
-                       gpointer new_environ, const gunichar2 *cwd,
-                       WapiStartupInfo *startup,
-                       WapiProcessInformation *process_info)
-{
-#if defined (HAVE_FORK) && defined (HAVE_EXECVE)
-       char *cmd = NULL, *prog = NULL, *full_prog = NULL, *args = NULL, *args_after_prog = NULL;
-       char *dir = NULL, **env_strings = NULL, **argv = NULL;
-       guint32 i, env_count = 0;
-       gboolean ret = FALSE;
-       gpointer handle = NULL;
-       WapiHandle_process process_handle = {0}, *process_handle_data;
-       GError *gerr = NULL;
-       int in_fd, out_fd, err_fd;
-       pid_t pid = 0;
-       int startup_pipe [2] = {-1, -1};
-       int dummy;
-       struct MonoProcess *mono_process;
-       gboolean fork_failed = FALSE;
-
-       mono_once (&process_sig_chld_once, process_add_sigchld_handler);
-
-       /* appname and cmdline specify the executable and its args:
-        *
-        * If appname is not NULL, it is the name of the executable.
-        * Otherwise the executable is the first token in cmdline.
-        *
-        * Executable searching:
-        *
-        * If appname is not NULL, it can specify the full path and
-        * file name, or else a partial name and the current directory
-        * will be used.  There is no additional searching.
-        *
-        * If appname is NULL, the first whitespace-delimited token in
-        * cmdline is used.  If the name does not contain a full
-        * directory path, the search sequence is:
-        *
-        * 1) The directory containing the current process
-        * 2) The current working directory
-        * 3) The windows system directory  (Ignored)
-        * 4) The windows directory (Ignored)
-        * 5) $PATH
-        *
-        * Just to make things more interesting, tokens can contain
-        * white space if they are surrounded by quotation marks.  I'm
-        * beginning to understand just why windows apps are generally
-        * so crap, with an API like this :-(
-        */
-       if (appname != NULL) {
-               cmd = mono_unicode_to_external (appname);
-               if (cmd == NULL) {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unicode conversion returned NULL",
-                                  __func__);
-
-                       SetLastError (ERROR_PATH_NOT_FOUND);
-                       goto free_strings;
-               }
-
-               switch_dir_separators(cmd);
-       }
-       
-       if (cmdline != NULL) {
-               args = mono_unicode_to_external (cmdline);
-               if (args == NULL) {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unicode conversion returned NULL", __func__);
-
-                       SetLastError (ERROR_PATH_NOT_FOUND);
-                       goto free_strings;
-               }
-       }
-
-       if (cwd != NULL) {
-               dir = mono_unicode_to_external (cwd);
-               if (dir == NULL) {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unicode conversion returned NULL", __func__);
-
-                       SetLastError (ERROR_PATH_NOT_FOUND);
-                       goto free_strings;
-               }
-
-               /* Turn all the slashes round the right way */
-               switch_dir_separators(dir);
-       }
-       
-
-       /* We can't put off locating the executable any longer :-( */
-       if (cmd != NULL) {
-               char *unquoted;
-               if (g_ascii_isalpha (cmd[0]) && (cmd[1] == ':')) {
-                       /* Strip off the drive letter.  I can't
-                        * believe that CP/M holdover is still
-                        * visible...
-                        */
-                       g_memmove (cmd, cmd+2, strlen (cmd)-2);
-                       cmd[strlen (cmd)-2] = '\0';
-               }
-
-               unquoted = g_shell_unquote (cmd, NULL);
-               if (unquoted[0] == '/') {
-                       /* Assume full path given */
-                       prog = g_strdup (unquoted);
-
-                       /* Executable existing ? */
-                       if (!is_readable_or_executable (prog)) {
-                               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Couldn't find executable %s",
-                                          __func__, prog);
-                               g_free (unquoted);
-                               SetLastError (ERROR_FILE_NOT_FOUND);
-                               goto free_strings;
-                       }
-               } else {
-                       /* Search for file named by cmd in the current
-                        * directory
-                        */
-                       char *curdir = g_get_current_dir ();
-
-                       prog = g_strdup_printf ("%s/%s", curdir, unquoted);
-                       g_free (curdir);
-
-                       /* And make sure it's readable */
-                       if (!is_readable_or_executable (prog)) {
-                               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Couldn't find executable %s",
-                                          __func__, prog);
-                               g_free (unquoted);
-                               SetLastError (ERROR_FILE_NOT_FOUND);
-                               goto free_strings;
-                       }
-               }
-               g_free (unquoted);
-
-               args_after_prog = args;
-       } else {
-               char *token = NULL;
-               char quote;
-               
-               /* Dig out the first token from args, taking quotation
-                * marks into account
-                */
-
-               /* First, strip off all leading whitespace */
-               args = g_strchug (args);
-               
-               /* args_after_prog points to the contents of args
-                * after token has been set (otherwise argv[0] is
-                * duplicated)
-                */
-               args_after_prog = args;
-
-               /* Assume the opening quote will always be the first
-                * character
-                */
-               if (args[0] == '\"' || args [0] == '\'') {
-                       quote = args [0];
-                       for (i = 1; args[i] != '\0' && args[i] != quote; i++);
-                       if (args [i + 1] == '\0' || g_ascii_isspace (args[i+1])) {
-                               /* We found the first token */
-                               token = g_strndup (args+1, i-1);
-                               args_after_prog = g_strchug (args + i + 1);
-                       } else {
-                               /* Quotation mark appeared in the
-                                * middle of the token.  Just give the
-                                * whole first token, quotes and all,
-                                * to exec.
-                                */
-                       }
-               }
-               
-               if (token == NULL) {
-                       /* No quote mark, or malformed */
-                       for (i = 0; args[i] != '\0'; i++) {
-                               if (g_ascii_isspace (args[i])) {
-                                       token = g_strndup (args, i);
-                                       args_after_prog = args + i + 1;
-                                       break;
-                               }
-                       }
-               }
-
-               if (token == NULL && args[0] != '\0') {
-                       /* Must be just one token in the string */
-                       token = g_strdup (args);
-                       args_after_prog = NULL;
-               }
-               
-               if (token == NULL) {
-                       /* Give up */
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Couldn't find what to exec", __func__);
-
-                       SetLastError (ERROR_PATH_NOT_FOUND);
-                       goto free_strings;
-               }
-               
-               /* Turn all the slashes round the right way. Only for
-                * the prg. name
-                */
-               switch_dir_separators(token);
-
-               if (g_ascii_isalpha (token[0]) && (token[1] == ':')) {
-                       /* Strip off the drive letter.  I can't
-                        * believe that CP/M holdover is still
-                        * visible...
-                        */
-                       g_memmove (token, token+2, strlen (token)-2);
-                       token[strlen (token)-2] = '\0';
-               }
-
-               if (token[0] == '/') {
-                       /* Assume full path given */
-                       prog = g_strdup (token);
-                       
-                       /* Executable existing ? */
-                       if (!is_readable_or_executable (prog)) {
-                               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Couldn't find executable %s",
-                                          __func__, token);
-                               g_free (token);
-                               SetLastError (ERROR_FILE_NOT_FOUND);
-                               goto free_strings;
-                       }
-               } else {
-                       char *curdir = g_get_current_dir ();
-
-                       /* FIXME: Need to record the directory
-                        * containing the current process, and check
-                        * that for the new executable as the first
-                        * place to look
-                        */
-
-                       prog = g_strdup_printf ("%s/%s", curdir, token);
-                       g_free (curdir);
-
-                       /* I assume X_OK is the criterion to use,
-                        * rather than F_OK
-                        *
-                        * X_OK is too strict *if* the target is a CLR binary
-                        */
-                       if (!is_readable_or_executable (prog)) {
-                               g_free (prog);
-                               prog = g_find_program_in_path (token);
-                               if (prog == NULL) {
-                                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Couldn't find executable %s", __func__, token);
-
-                                       g_free (token);
-                                       SetLastError (ERROR_FILE_NOT_FOUND);
-                                       goto free_strings;
-                               }
-                       }
-               }
-
-               g_free (token);
-       }
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Exec prog [%s] args [%s]", __func__, prog,
-                  args_after_prog);
-       
-       /* Check for CLR binaries; if found, we will try to invoke
-        * them using the same mono binary that started us.
-        */
-       if (is_managed_binary (prog)) {
-               gunichar2 *newapp = NULL, *newcmd;
-               gsize bytes_ignored;
-
-               if (cli_launcher)
-                       newapp = mono_unicode_from_external (cli_launcher, &bytes_ignored);
-               else
-                       newapp = mono_unicode_from_external ("mono", &bytes_ignored);
-
-               if (newapp != NULL) {
-                       if (appname != NULL) {
-                               newcmd = utf16_concat (utf16_quote, newapp, utf16_quote, utf16_space,
-                                                      appname, utf16_space,
-                                                      cmdline, NULL);
-                       } else {
-                               newcmd = utf16_concat (utf16_quote, newapp, utf16_quote, utf16_space,
-                                                      cmdline, NULL);
-                       }
-                       
-                       g_free ((gunichar2 *)newapp);
-                       
-                       if (newcmd != NULL) {
-                               ret = CreateProcess (NULL, newcmd,
-                                                    process_attrs,
-                                                    thread_attrs,
-                                                    inherit_handles,
-                                                    create_flags, new_environ,
-                                                    cwd, startup,
-                                                    process_info);
-                               
-                               g_free ((gunichar2 *)newcmd);
-                               
-                               goto free_strings;
-                       }
-               }
-       } else {
-               if (!is_executable (prog)) {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Executable permisson not set on %s", __func__, prog);
-                       SetLastError (ERROR_ACCESS_DENIED);
-                       goto free_strings;
-               }
-       }
-
-       if (args_after_prog != NULL && *args_after_prog) {
-               char *qprog;
-
-               qprog = g_shell_quote (prog);
-               full_prog = g_strconcat (qprog, " ", args_after_prog, NULL);
-               g_free (qprog);
-       } else {
-               full_prog = g_shell_quote (prog);
-       }
-
-       ret = g_shell_parse_argv (full_prog, NULL, &argv, &gerr);
-       if (ret == FALSE) {
-               g_message ("CreateProcess: %s\n", gerr->message);
-               g_error_free (gerr);
-               gerr = NULL;
-               goto free_strings;
-       }
-
-       if (startup != NULL && startup->dwFlags & STARTF_USESTDHANDLES) {
-               in_fd = GPOINTER_TO_UINT (startup->hStdInput);
-               out_fd = GPOINTER_TO_UINT (startup->hStdOutput);
-               err_fd = GPOINTER_TO_UINT (startup->hStdError);
-       } else {
-               in_fd = GPOINTER_TO_UINT (GetStdHandle (STD_INPUT_HANDLE));
-               out_fd = GPOINTER_TO_UINT (GetStdHandle (STD_OUTPUT_HANDLE));
-               err_fd = GPOINTER_TO_UINT (GetStdHandle (STD_ERROR_HANDLE));
-       }
-       
-       process_handle.proc_name = g_strdup (prog);
-
-       process_set_defaults (&process_handle);
-       
-       handle = mono_w32handle_new (MONO_W32HANDLE_PROCESS, &process_handle);
-       if (handle == INVALID_HANDLE_VALUE) {
-               g_warning ("%s: error creating process handle", __func__);
-
-               ret = FALSE;
-               SetLastError (ERROR_OUTOFMEMORY);
-               goto free_strings;
-       }
-
-       /* new_environ is a block of NULL-terminated strings, which
-        * is itself NULL-terminated. Of course, passing an array of
-        * string pointers would have made things too easy :-(
-        *
-        * If new_environ is not NULL it specifies the entire set of
-        * environment variables in the new process.  Otherwise the
-        * new process inherits the same environment.
-        */
-       if (new_environ) {
-               gunichar2 *new_environp;
-
-               /* Count the number of strings */
-               for (new_environp = (gunichar2 *)new_environ; *new_environp;
-                    new_environp++) {
-                       env_count++;
-                       while (*new_environp) {
-                               new_environp++;
-                       }
-               }
-
-               /* +2: one for the process handle value, and the last
-                * one is NULL
-                */
-               env_strings = g_new0 (char *, env_count + 2);
-               
-               /* Copy each environ string into 'strings' turning it
-                * into utf8 (or the requested encoding) at the same
-                * time
-                */
-               env_count = 0;
-               for (new_environp = (gunichar2 *)new_environ; *new_environp;
-                    new_environp++) {
-                       env_strings[env_count] = mono_unicode_to_external (new_environp);
-                       env_count++;
-                       while (*new_environp) {
-                               new_environp++;
-                       }
-               }
-       } else {
-               for (i = 0; environ[i] != NULL; i++)
-                       env_count++;
-
-               /* +2: one for the process handle value, and the last
-                * one is NULL
-                */
-               env_strings = g_new0 (char *, env_count + 2);
-               
-               /* Copy each environ string into 'strings' turning it
-                * into utf8 (or the requested encoding) at the same
-                * time
-                */
-               env_count = 0;
-               for (i = 0; environ[i] != NULL; i++) {
-                       env_strings[env_count] = g_strdup (environ[i]);
-                       env_count++;
-               }
-       }
-
-       /* Create a pipe to make sure the child doesn't exit before 
-        * we can add the process to the linked list of mono_processes */
-       if (pipe (startup_pipe) == -1) {
-               /* Could not create the pipe to synchroniz process startup. We'll just not synchronize.
-                * This is just for a very hard to hit race condition in the first place */
-               startup_pipe [0] = startup_pipe [1] = -1;
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: new process startup not synchronized. We may not notice if the newly created process exits immediately.", __func__);
-       }
-
-       switch (pid = fork ()) {
-       case -1: /* Error */ {
-               SetLastError (ERROR_OUTOFMEMORY);
-               ret = FALSE;
-               fork_failed = TRUE;
-               break;
-       }
-       case 0: /* Child */ {
-               if (startup_pipe [0] != -1) {
-                       /* Wait until the parent has updated it's internal data */
-                       ssize_t _i G_GNUC_UNUSED = read (startup_pipe [0], &dummy, 1);
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: child: parent has completed its setup", __func__);
-                       close (startup_pipe [0]);
-                       close (startup_pipe [1]);
-               }
-               
-               /* should we detach from the process group? */
-
-               /* Connect stdin, stdout and stderr */
-               dup2 (in_fd, 0);
-               dup2 (out_fd, 1);
-               dup2 (err_fd, 2);
-
-               if (inherit_handles != TRUE) {
-                       /* FIXME: do something here */
-               }
-               
-               /* Close all file descriptors */
-               for (i = mono_w32handle_fd_reserve - 1; i > 2; i--)
-                       close (i);
-
-#ifdef DEBUG_ENABLED
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: exec()ing [%s] in dir [%s]", __func__, cmd,
-                          dir == NULL?".":dir);
-               for (i = 0; argv[i] != NULL; i++)
-                       g_message ("arg %d: [%s]", i, argv[i]);
-               
-               for (i = 0; env_strings[i] != NULL; i++)
-                       g_message ("env %d: [%s]", i, env_strings[i]);
-#endif
-
-               /* set cwd */
-               if (dir != NULL && chdir (dir) == -1) {
-                       /* set error */
-                       _exit (-1);
-               }
-               
-               /* exec */
-               execve (argv[0], argv, env_strings);
-               
-               /* set error */
-               _exit (-1);
-
-               break;
-       }
-       default: /* Parent */ {
-               process_handle_data = lookup_process_handle (handle);
-               if (!process_handle_data) {
-                       g_warning ("%s: error looking up process handle %p", __func__, handle);
-                       mono_w32handle_unref (handle);
-               } else {
-                       process_handle_data->id = pid;
-
-                       /* Add our mono_process into the linked list of mono_processes */
-                       mono_process = (struct MonoProcess *) g_malloc0 (sizeof (struct MonoProcess));
-                       mono_process->pid = pid;
-                       mono_process->handle_count = 1;
-                       mono_os_sem_init (&mono_process->exit_sem, 0);
-
-                       /* Keep the process handle artificially alive until the process
-                        * exits so that the information in the handle isn't lost. */
-                       mono_w32handle_ref (handle);
-                       mono_process->handle = handle;
-
-                       process_handle_data->mono_process = mono_process;
-
-                       mono_os_mutex_lock (&mono_processes_mutex);
-                       mono_process->next = mono_processes;
-                       mono_processes = mono_process;
-                       mono_os_mutex_unlock (&mono_processes_mutex);
-
-                       if (process_info != NULL) {
-                               process_info->hProcess = handle;
-                               process_info->dwProcessId = pid;
-
-                               /* FIXME: we might need to handle the thread info some day */
-                               process_info->hThread = INVALID_HANDLE_VALUE;
-                               process_info->dwThreadId = 0;
-                       }
-               }
-
-               break;
-       }
-       }
-
-       if (fork_failed)
-               mono_w32handle_unref (handle);
-
-       if (startup_pipe [1] != -1) {
-               /* Write 1 byte, doesn't matter what */
-               ssize_t _i G_GNUC_UNUSED = write (startup_pipe [1], startup_pipe, 1);
-               close (startup_pipe [0]);
-               close (startup_pipe [1]);
-       }
-
-free_strings:
-       if (cmd)
-               g_free (cmd);
-       if (full_prog)
-               g_free (full_prog);
-       if (prog)
-               g_free (prog);
-       if (args)
-               g_free (args);
-       if (dir)
-               g_free (dir);
-       if (env_strings)
-               g_strfreev (env_strings);
-       if (argv)
-               g_strfreev (argv);
-       
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning handle %p for pid %d", __func__, handle, pid);
-
-       /* Check if something needs to be cleaned up. */
-       mono_processes_cleanup ();
-       
-       return ret;
-#else
-       SetLastError (ERROR_NOT_SUPPORTED);
-       return FALSE;
-#endif // defined (HAVE_FORK) && defined (HAVE_EXECVE)
-}
-               
-static void
-process_set_name (WapiHandle_process *process_handle)
-{
-       char *progname, *utf8_progname, *slash;
-       
-       progname = g_get_prgname ();
-       utf8_progname = mono_utf8_from_external (progname);
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: using [%s] as prog name", __func__, progname);
-
-       if (utf8_progname) {
-               slash = strrchr (utf8_progname, '/');
-               if (slash)
-                       process_handle->proc_name = g_strdup (slash+1);
-               else
-                       process_handle->proc_name = g_strdup (utf8_progname);
-               g_free (utf8_progname);
-       }
-}
-
-void
-_wapi_processes_init (void)
-{
-       pid_t pid = wapi_getpid ();
-       WapiHandle_process process_handle = {0};
-
-       mono_w32handle_register_ops (MONO_W32HANDLE_PROCESS, &_wapi_process_ops);
-
-       mono_w32handle_register_capabilities (MONO_W32HANDLE_PROCESS,
-               (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SPECIAL_WAIT));
-       
-       process_handle.id = pid;
-
-       process_set_defaults (&process_handle);
-       process_set_name (&process_handle);
-
-       current_process = mono_w32handle_new (MONO_W32HANDLE_PROCESS,
-                                           &process_handle);
-       g_assert (current_process);
-
-       mono_os_mutex_init (&mono_processes_mutex);
-}
-
-gpointer
-_wapi_process_duplicate (void)
-{
-       mono_w32handle_ref (current_process);
-       
-       return current_process;
-}
-
-/* Returns a pseudo handle that doesn't need to be closed afterwards */
-gpointer
-GetCurrentProcess (void)
-{
-       return _WAPI_PROCESS_CURRENT;
-}
-
-guint32
-GetProcessId (gpointer handle)
-{
-       WapiHandle_process *process_handle;
-
-       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (handle))
-               /* This is a pseudo handle */
-               return WAPI_HANDLE_TO_PID (handle);
-       
-       process_handle = lookup_process_handle (handle);
-       if (!process_handle) {
-               SetLastError (ERROR_INVALID_HANDLE);
-               return 0;
-       }
-       
-       return process_handle->id;
-}
-
-static gboolean
-process_open_compare (gpointer handle, gpointer user_data)
-{
-       pid_t wanted_pid;
-       WapiHandle_process *process_handle;
-       pid_t checking_pid;
-
-       g_assert (!WAPI_IS_PSEUDO_PROCESS_HANDLE (handle));
-       
-       process_handle = lookup_process_handle (handle);
-       g_assert (process_handle);
-       
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: looking at process %d", __func__, process_handle->id);
-
-       checking_pid = process_handle->id;
-
-       if (checking_pid == 0)
-               return FALSE;
-       
-       wanted_pid = GPOINTER_TO_UINT (user_data);
-
-       /* It's possible to have more than one process handle with the
-        * same pid, but only the one running process can be
-        * unsignalled
-        */
-       if (checking_pid == wanted_pid &&
-           !mono_w32handle_issignalled (handle)) {
-               /* If the handle is blown away in the window between
-                * returning TRUE here and mono_w32handle_search pinging
-                * the timestamp, the search will continue
-                */
-               return TRUE;
-       } else {
-               return FALSE;
-       }
-}
-
-gboolean
-CloseProcess (gpointer handle)
-{
-       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (handle))
-               return TRUE;
-       return CloseHandle (handle);
-}
-
-/*
- * The caller owns the returned handle and must call CloseProcess () on it to clean it up.
- */
-gpointer
-OpenProcess (guint32 req_access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, guint32 pid)
-{
-       /* Find the process handle that corresponds to pid */
-       gpointer handle = NULL;
-       
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: looking for process %d", __func__, pid);
-
-       handle = mono_w32handle_search (MONO_W32HANDLE_PROCESS,
-                                     process_open_compare,
-                                     GUINT_TO_POINTER (pid), NULL, TRUE);
-       if (handle == 0) {
-               if (is_pid_valid (pid)) {
-                       /* Return a pseudo handle for processes we
-                        * don't have handles for
-                        */
-                       return WAPI_PID_TO_HANDLE (pid);
-               } else {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find pid %d", __func__, pid);
-
-                       SetLastError (ERROR_PROC_NOT_FOUND);
-       
-                       return NULL;
-               }
-       }
-
-       /* mono_w32handle_search () already added a ref */
-       return handle;
-}
-
-gboolean
-GetExitCodeProcess (gpointer process, guint32 *code)
-{
-       WapiHandle_process *process_handle;
-       guint32 pid = -1;
-       gboolean alerted;
-       
-       if (!code)
-               return FALSE;
-       
-       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) {
-               pid = WAPI_HANDLE_TO_PID (process);
-               /* This is a pseudo handle, so we don't know what the
-                * exit code was, but we can check whether it's alive or not
-                */
-               if (is_pid_valid (pid)) {
-                       *code = STILL_ACTIVE;
-                       return TRUE;
-               } else {
-                       *code = -1;
-                       return TRUE;
-               }
-       }
-
-       process_handle = lookup_process_handle (process);
-       if (!process_handle) {
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, process);
-               
-               return FALSE;
-       }
-
-       if (process_handle->id == wapi_getpid ()) {
-               *code = STILL_ACTIVE;
-               return TRUE;
-       }
-
-       /* A process handle is only signalled if the process has exited
-        * and has been waited for */
-
-       /* Make sure any process exit has been noticed, before
-        * checking if the process is signalled.  Fixes bug 325463.
-        */
-       process_wait (process, 0, &alerted);
-       
-       if (mono_w32handle_issignalled (process))
-               *code = process_handle->exitstatus;
-       else
-               *code = STILL_ACTIVE;
-       
-       return TRUE;
-}
-
-gboolean
-GetProcessTimes (gpointer process, WapiFileTime *create_time,
-                                WapiFileTime *exit_time, WapiFileTime *kernel_time,
-                                WapiFileTime *user_time)
-{
-       WapiHandle_process *process_handle;
-       gboolean ku_times_set = FALSE;
-       
-       if (create_time == NULL || exit_time == NULL || kernel_time == NULL ||
-               user_time == NULL)
-               /* Not sure if w32 allows NULLs here or not */
-               return FALSE;
-       
-       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) {
-               gpointer pid = GINT_TO_POINTER (WAPI_HANDLE_TO_PID(process));
-               gint64 start_ticks, user_ticks, kernel_ticks;
-
-               mono_process_get_times (pid, &start_ticks, &user_ticks, &kernel_ticks);
-
-               _wapi_guint64_to_filetime (start_ticks, create_time);
-               _wapi_guint64_to_filetime (user_ticks, kernel_time);
-               _wapi_guint64_to_filetime (kernel_ticks, user_time);
-
-               return TRUE;
-       }
-
-       process_handle = lookup_process_handle (process);
-       if (!process_handle) {
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, process);
-               
-               return FALSE;
-       }
-       
-       *create_time = process_handle->create_time;
-
-       /* A process handle is only signalled if the process has
-        * exited.  Otherwise exit_time isn't set
-        */
-       if (mono_w32handle_issignalled (process))
-               *exit_time = process_handle->exit_time;
-
-#ifdef HAVE_GETRUSAGE
-       if (process_handle->id == getpid ()) {
-               struct rusage time_data;
-               if (getrusage (RUSAGE_SELF, &time_data) == 0) {
-                       guint64 tick_val;
-                       ku_times_set = TRUE;
-                       tick_val = (guint64)time_data.ru_utime.tv_sec * 10000000 + (guint64)time_data.ru_utime.tv_usec * 10;
-                       _wapi_guint64_to_filetime (tick_val, user_time);
-                       tick_val = (guint64)time_data.ru_stime.tv_sec * 10000000 + (guint64)time_data.ru_stime.tv_usec * 10;
-                       _wapi_guint64_to_filetime (tick_val, kernel_time);
-               }
-       }
-#endif
-       if (!ku_times_set) {
-               memset (kernel_time, 0, sizeof (WapiFileTime));
-               memset (user_time, 0, sizeof (WapiFileTime));
-       }
-
-       return TRUE;
-}
-
-typedef struct
-{
-       gpointer address_start;
-       gpointer address_end;
-       char *perms;
-       gpointer address_offset;
-       guint64 device;
-       guint64 inode;
-       char *filename;
-} WapiProcModule;
-
-static void free_procmodule (WapiProcModule *mod)
-{
-       if (mod->perms != NULL) {
-               g_free (mod->perms);
-       }
-       if (mod->filename != NULL) {
-               g_free (mod->filename);
-       }
-       g_free (mod);
-}
-
-static gint find_procmodule (gconstpointer a, gconstpointer b)
-{
-       WapiProcModule *want = (WapiProcModule *)a;
-       WapiProcModule *compare = (WapiProcModule *)b;
-       
-       if ((want->device == compare->device) &&
-           (want->inode == compare->inode)) {
-               return(0);
-       } else {
-               return(1);
-       }
-}
-
-#if defined(USE_OSX_LOADER)
-#include <mach-o/dyld.h>
-#include <mach-o/getsect.h>
-
-static GSList *load_modules (void)
-{
-       GSList *ret = NULL;
-       WapiProcModule *mod;
-       uint32_t count = _dyld_image_count ();
-       int i = 0;
-
-       for (i = 0; i < count; i++) {
-#if SIZEOF_VOID_P == 8
-               const struct mach_header_64 *hdr;
-               const struct section_64 *sec;
-#else
-               const struct mach_header *hdr;
-               const struct section *sec;
-#endif
-               const char *name;
-
-               name = _dyld_get_image_name (i);
-#if SIZEOF_VOID_P == 8
-               hdr = (const struct mach_header_64*)_dyld_get_image_header (i);
-               sec = getsectbynamefromheader_64 (hdr, SEG_DATA, SECT_DATA);
-#else
-               hdr = _dyld_get_image_header (i);
-               sec = getsectbynamefromheader (hdr, SEG_DATA, SECT_DATA);
-#endif
-
-               /* Some dynlibs do not have data sections on osx (#533893) */
-               if (sec == 0) {
-                       continue;
-               }
-                       
-               mod = g_new0 (WapiProcModule, 1);
-               mod->address_start = GINT_TO_POINTER (sec->addr);
-               mod->address_end = GINT_TO_POINTER (sec->addr+sec->size);
-               mod->perms = g_strdup ("r--p");
-               mod->address_offset = 0;
-               mod->device = makedev (0, 0);
-               mod->inode = i;
-               mod->filename = g_strdup (name); 
-               
-               if (g_slist_find_custom (ret, mod, find_procmodule) == NULL) {
-                       ret = g_slist_prepend (ret, mod);
-               } else {
-                       free_procmodule (mod);
-               }
-       }
-
-       ret = g_slist_reverse (ret);
-       
-       return(ret);
-}
-#elif defined(USE_BSD_LOADER)
-#include <link.h>
-static int load_modules_callback (struct dl_phdr_info *info, size_t size, void *ptr)
-{
-       if (size < offsetof (struct dl_phdr_info, dlpi_phnum)
-           + sizeof (info->dlpi_phnum))
-               return (-1);
-
-       struct dl_phdr_info *cpy = g_calloc (1, sizeof(struct dl_phdr_info));
-       if (!cpy)
-               return (-1);
-
-       memcpy(cpy, info, sizeof(*info));
-
-       g_ptr_array_add ((GPtrArray *)ptr, cpy);
-
-       return (0);
-}
-
-static GSList *load_modules (void)
-{
-       GSList *ret = NULL;
-       WapiProcModule *mod;
-       GPtrArray *dlarray = g_ptr_array_new();
-       int i;
-
-       if (dl_iterate_phdr(load_modules_callback, dlarray) < 0)
-               return (ret);
-
-       for (i = 0; i < dlarray->len; i++) {
-               struct dl_phdr_info *info = g_ptr_array_index (dlarray, i);
-
-               mod = g_new0 (WapiProcModule, 1);
-               mod->address_start = (gpointer)(info->dlpi_addr + info->dlpi_phdr[0].p_vaddr);
-               mod->address_end = (gpointer)(info->dlpi_addr +
-                                       info->dlpi_phdr[info->dlpi_phnum - 1].p_vaddr);
-               mod->perms = g_strdup ("r--p");
-               mod->address_offset = 0;
-               mod->inode = i;
-               mod->filename = g_strdup (info->dlpi_name); 
-
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: inode=%d, filename=%s, address_start=%p, address_end=%p", __func__,
-                                  mod->inode, mod->filename, mod->address_start, mod->address_end);
-
-               g_free (info);
-
-               if (g_slist_find_custom (ret, mod, find_procmodule) == NULL) {
-                       ret = g_slist_prepend (ret, mod);
-               } else {
-                       free_procmodule (mod);
-               }
-       }
-
-       g_ptr_array_free (dlarray, TRUE);
-
-       ret = g_slist_reverse (ret);
-
-       return(ret);
-}
-#elif defined(USE_HAIKU_LOADER)
-
-static GSList *load_modules (void)
-{
-       GSList *ret = NULL;
-       WapiProcModule *mod;
-       int32 cookie = 0;
-       image_info imageInfo;
-
-       while (get_next_image_info (B_CURRENT_TEAM, &cookie, &imageInfo) == B_OK) {
-               mod = g_new0 (WapiProcModule, 1);
-               mod->device = imageInfo.device;
-               mod->inode = imageInfo.node;
-               mod->filename = g_strdup (imageInfo.name);
-               mod->address_start = MIN (imageInfo.text, imageInfo.data);
-               mod->address_end = MAX ((uint8_t*)imageInfo.text + imageInfo.text_size,
-                       (uint8_t*)imageInfo.data + imageInfo.data_size);
-               mod->perms = g_strdup ("r--p");
-               mod->address_offset = 0;
-
-               if (g_slist_find_custom (ret, mod, find_procmodule) == NULL) {
-                       ret = g_slist_prepend (ret, mod);
-               } else {
-                       free_procmodule (mod);
-               }
-       }
-
-       ret = g_slist_reverse (ret);
-
-       return ret;
-}
-#else
-static GSList *load_modules (FILE *fp)
-{
-       GSList *ret = NULL;
-       WapiProcModule *mod;
-       char buf[MAXPATHLEN + 1], *p, *endp;
-       char *start_start, *end_start, *prot_start, *offset_start;
-       char *maj_dev_start, *min_dev_start, *inode_start, prot_buf[5];
-       gpointer address_start, address_end, address_offset;
-       guint32 maj_dev, min_dev;
-       guint64 inode;
-       guint64 device;
-       
-       while (fgets (buf, sizeof(buf), fp)) {
-               p = buf;
-               while (g_ascii_isspace (*p)) ++p;
-               start_start = p;
-               if (!g_ascii_isxdigit (*start_start)) {
-                       continue;
-               }
-               address_start = (gpointer)strtoul (start_start, &endp, 16);
-               p = endp;
-               if (*p != '-') {
-                       continue;
-               }
-               
-               ++p;
-               end_start = p;
-               if (!g_ascii_isxdigit (*end_start)) {
-                       continue;
-               }
-               address_end = (gpointer)strtoul (end_start, &endp, 16);
-               p = endp;
-               if (!g_ascii_isspace (*p)) {
-                       continue;
-               }
-               
-               while (g_ascii_isspace (*p)) ++p;
-               prot_start = p;
-               if (*prot_start != 'r' && *prot_start != '-') {
-                       continue;
-               }
-               memcpy (prot_buf, prot_start, 4);
-               prot_buf[4] = '\0';
-               while (!g_ascii_isspace (*p)) ++p;
-               
-               while (g_ascii_isspace (*p)) ++p;
-               offset_start = p;
-               if (!g_ascii_isxdigit (*offset_start)) {
-                       continue;
-               }
-               address_offset = (gpointer)strtoul (offset_start, &endp, 16);
-               p = endp;
-               if (!g_ascii_isspace (*p)) {
-                       continue;
-               }
-               
-               while(g_ascii_isspace (*p)) ++p;
-               maj_dev_start = p;
-               if (!g_ascii_isxdigit (*maj_dev_start)) {
-                       continue;
-               }
-               maj_dev = strtoul (maj_dev_start, &endp, 16);
-               p = endp;
-               if (*p != ':') {
-                       continue;
-               }
-               
-               ++p;
-               min_dev_start = p;
-               if (!g_ascii_isxdigit (*min_dev_start)) {
-                       continue;
-               }
-               min_dev = strtoul (min_dev_start, &endp, 16);
-               p = endp;
-               if (!g_ascii_isspace (*p)) {
-                       continue;
-               }
-               
-               while (g_ascii_isspace (*p)) ++p;
-               inode_start = p;
-               if (!g_ascii_isxdigit (*inode_start)) {
-                       continue;
-               }
-               inode = (guint64)strtol (inode_start, &endp, 10);
-               p = endp;
-               if (!g_ascii_isspace (*p)) {
-                       continue;
-               }
-
-               device = makedev ((int)maj_dev, (int)min_dev);
-               if ((device == 0) &&
-                   (inode == 0)) {
-                       continue;
-               }
-               
-               while(g_ascii_isspace (*p)) ++p;
-               /* p now points to the filename */
-
-               mod = g_new0 (WapiProcModule, 1);
-               mod->address_start = address_start;
-               mod->address_end = address_end;
-               mod->perms = g_strdup (prot_buf);
-               mod->address_offset = address_offset;
-               mod->device = device;
-               mod->inode = inode;
-               mod->filename = g_strdup (g_strstrip (p));
-               
-               if (g_slist_find_custom (ret, mod, find_procmodule) == NULL) {
-                       ret = g_slist_prepend (ret, mod);
-               } else {
-                       free_procmodule (mod);
-               }
-       }
-
-       ret = g_slist_reverse (ret);
-       
-       return(ret);
-}
-#endif
-
-static gboolean match_procname_to_modulename (char *procname, char *modulename)
-{
-       char* lastsep = NULL;
-       char* lastsep2 = NULL;
-       char* pname = NULL;
-       char* mname = NULL;
-       gboolean result = FALSE;
-
-       if (procname == NULL || modulename == NULL)
-               return (FALSE);
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: procname=\"%s\", modulename=\"%s\"", __func__, procname, modulename);
-       pname = mono_path_resolve_symlinks (procname);
-       mname = mono_path_resolve_symlinks (modulename);
-
-       if (!strcmp (pname, mname))
-               result = TRUE;
-
-       if (!result) {
-               lastsep = strrchr (mname, '/');
-               if (lastsep)
-                       if (!strcmp (lastsep+1, pname))
-                               result = TRUE;
-               if (!result) {
-                       lastsep2 = strrchr (pname, '/');
-                       if (lastsep2){
-                               if (lastsep) {
-                                       if (!strcmp (lastsep+1, lastsep2+1))
-                                               result = TRUE;
-                               } else {
-                                       if (!strcmp (mname, lastsep2+1))
-                                               result = TRUE;
-                               }
-                       }
-               }
-       }
-
-       g_free (pname);
-       g_free (mname);
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: result is %d", __func__, result);
-       return result;
-}
-
-#if !(defined(USE_OSX_LOADER) || defined(USE_BSD_LOADER) || defined(USE_HAIKU_LOADER))
-static FILE *
-open_process_map (int pid, const char *mode)
-{
-       FILE *fp = NULL;
-       const char *proc_path[] = {
-               "/proc/%d/maps",        /* GNU/Linux */
-               "/proc/%d/map",         /* FreeBSD */
-               NULL
-       };
-       int i;
-       char *filename;
-
-       for (i = 0; fp == NULL && proc_path [i]; i++) {
-               filename = g_strdup_printf (proc_path[i], pid);
-               fp = fopen (filename, mode);
-               g_free (filename);
-       }
-
-       return fp;
-}
-#endif
-
-static char *get_process_name_from_proc (pid_t pid);
-
-gboolean EnumProcessModules (gpointer process, gpointer *modules,
-                            guint32 size, guint32 *needed)
-{
-       WapiHandle_process *process_handle;
-#if !defined(USE_OSX_LOADER) && !defined(USE_BSD_LOADER)
-       FILE *fp;
-#endif
-       GSList *mods = NULL;
-       WapiProcModule *module;
-       guint32 count, avail = size / sizeof(gpointer);
-       int i;
-       pid_t pid;
-       char *proc_name = NULL;
-       
-       /* Store modules in an array of pointers (main module as
-        * modules[0]), using the load address for each module as a
-        * token.  (Use 'NULL' as an alternative for the main module
-        * so that the simple implementation can just return one item
-        * for now.)  Get the info from /proc/<pid>/maps on linux,
-        * /proc/<pid>/map on FreeBSD, other systems will have to
-        * implement /dev/kmem reading or whatever other horrid
-        * technique is needed.
-        */
-       if (size < sizeof(gpointer))
-               return FALSE;
-
-       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) {
-               pid = WAPI_HANDLE_TO_PID (process);
-               proc_name = get_process_name_from_proc (pid);
-       } else {
-               process_handle = lookup_process_handle (process);
-               if (!process_handle) {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, process);
-               
-                       return FALSE;
-               }
-               pid = process_handle->id;
-               proc_name = g_strdup (process_handle->proc_name);
-       }
-       
-#if defined(USE_OSX_LOADER) || defined(USE_BSD_LOADER) || defined(USE_HAIKU_LOADER)
-       mods = load_modules ();
-       if (!proc_name) {
-               modules[0] = NULL;
-               *needed = sizeof(gpointer);
-               return TRUE;
-       }
-#else
-       fp = open_process_map (pid, "r");
-       if (!fp) {
-               /* No /proc/<pid>/maps so just return the main module
-                * shortcut for now
-                */
-               modules[0] = NULL;
-               *needed = sizeof(gpointer);
-               g_free (proc_name);
-               return TRUE;
-       }
-       mods = load_modules (fp);
-       fclose (fp);
-#endif
-       count = g_slist_length (mods);
-               
-       /* count + 1 to leave slot 0 for the main module */
-       *needed = sizeof(gpointer) * (count + 1);
-
-       /*
-        * Use the NULL shortcut, as the first line in
-        * /proc/<pid>/maps isn't the executable, and we need
-        * that first in the returned list. Check the module name 
-        * to see if it ends with the proc name and substitute 
-        * the first entry with it.  FIXME if this turns out to 
-        * be a problem.
-        */
-       modules[0] = NULL;
-       for (i = 0; i < (avail - 1) && i < count; i++) {
-               module = (WapiProcModule *)g_slist_nth_data (mods, i);
-               if (modules[0] != NULL)
-                       modules[i] = module->address_start;
-               else if (match_procname_to_modulename (proc_name, module->filename))
-                       modules[0] = module->address_start;
-               else
-                       modules[i + 1] = module->address_start;
-       }
-               
-       for (i = 0; i < count; i++) {
-               free_procmodule ((WapiProcModule *)g_slist_nth_data (mods, i));
-       }
-       g_slist_free (mods);
-       g_free (proc_name);
-       
-       return TRUE;
-}
-
-static char *
-get_process_name_from_proc (pid_t pid)
-{
-#if defined(USE_BSD_LOADER)
-       int mib [6];
-       size_t size;
-       struct kinfo_proc *pi;
-#elif defined(USE_OSX_LOADER)
-#if !(!defined (__mono_ppc__) && defined (TARGET_OSX))
-       size_t size;
-       struct kinfo_proc *pi;
-       int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid };
-#endif
-#else
-       FILE *fp;
-       char *filename = NULL;
-#endif
-       char buf[256];
-       char *ret = NULL;
-
-#if defined(PLATFORM_SOLARIS)
-       filename = g_strdup_printf ("/proc/%d/psinfo", pid);
-       if ((fp = fopen (filename, "r")) != NULL) {
-               struct psinfo info;
-               int nread;
-
-               nread = fread (&info, sizeof (info), 1, fp);
-               if (nread == 1) {
-                       ret = g_strdup (info.pr_fname);
-               }
-
-               fclose (fp);
-       }
-       g_free (filename);
-#elif defined(USE_OSX_LOADER)
-#if !defined (__mono_ppc__) && defined (TARGET_OSX)
-       /* No proc name on OSX < 10.5 nor ppc nor iOS */
-       memset (buf, '\0', sizeof(buf));
-       proc_name (pid, buf, sizeof(buf));
-
-       // Fixes proc_name triming values to 15 characters #32539
-       if (strlen (buf) >= MAXCOMLEN - 1) {
-               char path_buf [PROC_PIDPATHINFO_MAXSIZE];
-               char *name_buf;
-               int path_len;
-
-               memset (path_buf, '\0', sizeof(path_buf));
-               path_len = proc_pidpath (pid, path_buf, sizeof(path_buf));
-
-               if (path_len > 0 && path_len < sizeof(path_buf)) {
-                       name_buf = path_buf + path_len;
-                       for(;name_buf > path_buf; name_buf--) {
-                               if (name_buf [0] == '/') {
-                                       name_buf++;
-                                       break;
-                               }
-                       }
-
-                       if (memcmp (buf, name_buf, MAXCOMLEN - 1) == 0)
-                               ret = g_strdup (name_buf);
-               }
-       }
-
-       if (ret == NULL && strlen (buf) > 0)
-               ret = g_strdup (buf);
-#else
-       if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0)
-               return(ret);
-
-       if ((pi = g_malloc (size)) == NULL)
-               return(ret);
-
-       if (sysctl (mib, 4, pi, &size, NULL, 0) < 0) {
-               if (errno == ENOMEM) {
-                       g_free (pi);
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Didn't allocate enough memory for kproc info", __func__);
-               }
-               return(ret);
-       }
-
-       if (strlen (pi->kp_proc.p_comm) > 0)
-               ret = g_strdup (pi->kp_proc.p_comm);
-
-       g_free (pi);
-#endif
-#elif defined(USE_BSD_LOADER)
-#if defined(__FreeBSD__)
-       mib [0] = CTL_KERN;
-       mib [1] = KERN_PROC;
-       mib [2] = KERN_PROC_PID;
-       mib [3] = pid;
-       if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0) {
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: sysctl() failed: %d", __func__, errno);
-               return(ret);
-       }
-
-       if ((pi = g_malloc (size)) == NULL)
-               return(ret);
-
-       if (sysctl (mib, 4, pi, &size, NULL, 0) < 0) {
-               if (errno == ENOMEM) {
-                       g_free (pi);
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Didn't allocate enough memory for kproc info", __func__);
-               }
-               return(ret);
-       }
-
-       if (strlen (pi->ki_comm) > 0)
-               ret = g_strdup (pi->ki_comm);
-       g_free (pi);
-#elif defined(__OpenBSD__)
-       mib [0] = CTL_KERN;
-       mib [1] = KERN_PROC;
-       mib [2] = KERN_PROC_PID;
-       mib [3] = pid;
-       mib [4] = sizeof(struct kinfo_proc);
-       mib [5] = 0;
-
-retry:
-       if (sysctl(mib, 6, NULL, &size, NULL, 0) < 0) {
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: sysctl() failed: %d", __func__, errno);
-               return(ret);
-       }
-
-       if ((pi = g_malloc (size)) == NULL)
-               return(ret);
-
-       mib[5] = (int)(size / sizeof(struct kinfo_proc));
-
-       if ((sysctl (mib, 6, pi, &size, NULL, 0) < 0) ||
-               (size != sizeof (struct kinfo_proc))) {
-               if (errno == ENOMEM) {
-                       g_free (pi);
-                       goto retry;
-               }
-               return(ret);
-       }
-
-       if (strlen (pi->p_comm) > 0)
-               ret = g_strdup (pi->p_comm);
-
-       g_free (pi);
-#endif
-#elif defined(USE_HAIKU_LOADER)
-       image_info imageInfo;
-       int32 cookie = 0;
-
-       if (get_next_image_info ((team_id)pid, &cookie, &imageInfo) == B_OK) {
-               ret = g_strdup (imageInfo.name);
-       }
-#else
-       memset (buf, '\0', sizeof(buf));
-       filename = g_strdup_printf ("/proc/%d/exe", pid);
-       if (readlink (filename, buf, 255) > 0) {
-               ret = g_strdup (buf);
-       }
-       g_free (filename);
-
-       if (ret != NULL) {
-               return(ret);
-       }
-
-       filename = g_strdup_printf ("/proc/%d/cmdline", pid);
-       if ((fp = fopen (filename, "r")) != NULL) {
-               if (fgets (buf, 256, fp) != NULL) {
-                       ret = g_strdup (buf);
-               }
-               
-               fclose (fp);
-       }
-       g_free (filename);
-
-       if (ret != NULL) {
-               return(ret);
-       }
-       
-       filename = g_strdup_printf ("/proc/%d/stat", pid);
-       if ((fp = fopen (filename, "r")) != NULL) {
-               if (fgets (buf, 256, fp) != NULL) {
-                       char *start, *end;
-                       
-                       start = strchr (buf, '(');
-                       if (start != NULL) {
-                               end = strchr (start + 1, ')');
-                               
-                               if (end != NULL) {
-                                       ret = g_strndup (start + 1,
-                                                        end - start - 1);
-                               }
-                       }
-               }
-               
-               fclose (fp);
-       }
-       g_free (filename);
-#endif
-
-       return ret;
-}
-
-/*
- * wapi_process_get_path:
- *
- *   Return the full path of the executable of the process PID, or NULL if it cannot be determined.
- * Returns malloc-ed memory.
- */
-char*
-wapi_process_get_path (pid_t pid)
-{
-#if defined(PLATFORM_MACOSX) && !defined(__mono_ppc__) && defined(TARGET_OSX)
-       char buf [PROC_PIDPATHINFO_MAXSIZE];
-       int res;
-
-       res = proc_pidpath (pid, buf, sizeof (buf));
-       if (res <= 0)
-               return NULL;
-       if (buf [0] == '\0')
-               return NULL;
-       return g_strdup (buf);
-#else
-       return get_process_name_from_proc (pid);
-#endif
-}
-
-/*
- * wapi_process_set_cli_launcher:
- *
- *   Set the full path of the runtime executable used to launch managed exe's.
- */
-void
-wapi_process_set_cli_launcher (char *path)
-{
-       g_free (cli_launcher);
-       cli_launcher = path ? g_strdup (path) : NULL;
-}
-
-static guint32
-get_module_name (gpointer process, gpointer module,
-                                gunichar2 *basename, guint32 size,
-                                gboolean base)
-{
-       WapiHandle_process *process_handle;
-       pid_t pid;
-       gunichar2 *procname;
-       char *procname_ext = NULL;
-       glong len;
-       gsize bytes;
-#if !defined(USE_OSX_LOADER) && !defined(USE_BSD_LOADER)
-       FILE *fp;
-#endif
-       GSList *mods = NULL;
-       WapiProcModule *found_module;
-       guint32 count;
-       int i;
-       char *proc_name = NULL;
-       
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Getting module base name, process handle %p module %p",
-                  __func__, process, module);
-
-       size = size * sizeof (gunichar2); /* adjust for unicode characters */
-
-       if (basename == NULL || size == 0)
-               return 0;
-       
-       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) {
-               /* This is a pseudo handle */
-               pid = (pid_t)WAPI_HANDLE_TO_PID (process);
-               proc_name = get_process_name_from_proc (pid);
-       } else {
-               process_handle = lookup_process_handle (process);
-               if (!process_handle) {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__,
-                                  process);
-                       
-                       return 0;
-               }
-               pid = process_handle->id;
-               proc_name = g_strdup (process_handle->proc_name);
-       }
-
-       /* Look up the address in /proc/<pid>/maps */
-#if defined(USE_OSX_LOADER) || defined(USE_BSD_LOADER) || defined(USE_HAIKU_LOADER)
-       mods = load_modules ();
-#else
-       fp = open_process_map (pid, "r");
-       if (fp == NULL) {
-               if (errno == EACCES && module == NULL && base == TRUE) {
-                       procname_ext = get_process_name_from_proc (pid);
-               } else {
-                       /* No /proc/<pid>/maps, so just return failure
-                        * for now
-                        */
-                       g_free (proc_name);
-                       return 0;
-               }
-       } else {
-               mods = load_modules (fp);
-               fclose (fp);
-       }
-#endif
-       count = g_slist_length (mods);
-
-       /* If module != NULL compare the address.
-        * If module == NULL we are looking for the main module.
-        * The best we can do for now check it the module name end with the process name.
-        */
-       for (i = 0; i < count; i++) {
-               found_module = (WapiProcModule *)g_slist_nth_data (mods, i);
-               if (procname_ext == NULL &&
-                       ((module == NULL && match_procname_to_modulename (proc_name, found_module->filename)) ||
-                        (module != NULL && found_module->address_start == module))) {
-                       if (base)
-                               procname_ext = g_path_get_basename (found_module->filename);
-                       else
-                               procname_ext = g_strdup (found_module->filename);
-               }
-
-               free_procmodule (found_module);
-       }
-
-       if (procname_ext == NULL) {
-               /* If it's *still* null, we might have hit the
-                * case where reading /proc/$pid/maps gives an
-                * empty file for this user.
-                */
-               procname_ext = get_process_name_from_proc (pid);
-       }
-
-       g_slist_free (mods);
-       g_free (proc_name);
-
-       if (procname_ext) {
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Process name is [%s]", __func__,
-                          procname_ext);
-
-               procname = mono_unicode_from_external (procname_ext, &bytes);
-               if (procname == NULL) {
-                       /* bugger */
-                       g_free (procname_ext);
-                       return 0;
-               }
-               
-               len = (bytes / 2);
-               
-               /* Add the terminator */
-               bytes += 2;
-               
-               if (size < bytes) {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Size %d smaller than needed (%ld); truncating", __func__, size, bytes);
-
-                       memcpy (basename, procname, size);
-               } else {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Size %d larger than needed (%ld)",
-                                  __func__, size, bytes);
-
-                       memcpy (basename, procname, bytes);
-               }
-               
-               g_free (procname);
-               g_free (procname_ext);
-               
-               return len;
-       }
-       
-       return 0;
-}
-
-static guint32
-get_module_filename (gpointer process, gpointer module,
-                                        gunichar2 *basename, guint32 size)
-{
-       int pid, len;
-       gsize bytes;
-       char *path;
-       gunichar2 *proc_path;
-       
-       size *= sizeof (gunichar2); /* adjust for unicode characters */
-
-       if (basename == NULL || size == 0)
-               return 0;
-
-       pid = GetProcessId (process);
-
-       path = wapi_process_get_path (pid);
-       if (path == NULL)
-               return 0;
-
-       proc_path = mono_unicode_from_external (path, &bytes);
-       g_free (path);
-
-       if (proc_path == NULL)
-               return 0;
-
-       len = (bytes / 2);
-       
-       /* Add the terminator */
-       bytes += 2;
-
-       if (size < bytes) {
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Size %d smaller than needed (%ld); truncating", __func__, size, bytes);
-
-               memcpy (basename, proc_path, size);
-       } else {
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Size %d larger than needed (%ld)",
-                          __func__, size, bytes);
-
-               memcpy (basename, proc_path, bytes);
-       }
-
-       g_free (proc_path);
-
-       return len;
-}
-
-guint32
-GetModuleBaseName (gpointer process, gpointer module,
-                                  gunichar2 *basename, guint32 size)
-{
-       return get_module_name (process, module, basename, size, TRUE);
-}
-
-guint32
-GetModuleFileNameEx (gpointer process, gpointer module,
-                                        gunichar2 *filename, guint32 size)
-{
-       return get_module_filename (process, module, filename, size);
-}
-
-gboolean
-GetModuleInformation (gpointer process, gpointer module,
-                                         WapiModuleInfo *modinfo, guint32 size)
-{
-       WapiHandle_process *process_handle;
-       pid_t pid;
-#if !defined(USE_OSX_LOADER) && !defined(USE_BSD_LOADER)
-       FILE *fp;
-#endif
-       GSList *mods = NULL;
-       WapiProcModule *found_module;
-       guint32 count;
-       int i;
-       gboolean ret = FALSE;
-       char *proc_name = NULL;
-       
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Getting module info, process handle %p module %p",
-                  __func__, process, module);
-
-       if (modinfo == NULL || size < sizeof (WapiModuleInfo))
-               return FALSE;
-       
-       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) {
-               pid = (pid_t)WAPI_HANDLE_TO_PID (process);
-               proc_name = get_process_name_from_proc (pid);
-       } else {
-               process_handle = lookup_process_handle (process);
-               if (!process_handle) {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__,
-                                  process);
-                       
-                       return FALSE;
-               }
-               pid = process_handle->id;
-               proc_name = g_strdup (process_handle->proc_name);
-       }
-
-#if defined(USE_OSX_LOADER) || defined(USE_BSD_LOADER) || defined(USE_HAIKU_LOADER)
-       mods = load_modules ();
-#else
-       /* Look up the address in /proc/<pid>/maps */
-       if ((fp = open_process_map (pid, "r")) == NULL) {
-               /* No /proc/<pid>/maps, so just return failure
-                * for now
-                */
-               g_free (proc_name);
-               return FALSE;
-       }
-       mods = load_modules (fp);
-       fclose (fp);
-#endif
-       count = g_slist_length (mods);
-
-       /* If module != NULL compare the address.
-        * If module == NULL we are looking for the main module.
-        * The best we can do for now check it the module name end with the process name.
-        */
-       for (i = 0; i < count; i++) {
-                       found_module = (WapiProcModule *)g_slist_nth_data (mods, i);
-                       if (ret == FALSE &&
-                               ((module == NULL && match_procname_to_modulename (proc_name, found_module->filename)) ||
-                                (module != NULL && found_module->address_start == module))) {
-                               modinfo->lpBaseOfDll = found_module->address_start;
-                               modinfo->SizeOfImage = (gsize)(found_module->address_end) - (gsize)(found_module->address_start);
-                               modinfo->EntryPoint = found_module->address_offset;
-                               ret = TRUE;
-                       }
-
-                       free_procmodule (found_module);
-       }
-
-       g_slist_free (mods);
-       g_free (proc_name);
-
-       return ret;
-}
-
-gboolean
-GetProcessWorkingSetSize (gpointer process, size_t *min, size_t *max)
-{
-       WapiHandle_process *process_handle;
-       
-       if (min == NULL || max == NULL)
-               /* Not sure if w32 allows NULLs here or not */
-               return FALSE;
-       
-       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process))
-               /* This is a pseudo handle, so just fail for now */
-               return FALSE;
-       
-       process_handle = lookup_process_handle (process);
-       if (!process_handle) {
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, process);
-               
-               return FALSE;
-       }
-
-       *min = process_handle->min_working_set;
-       *max = process_handle->max_working_set;
-       
-       return TRUE;
-}
-
-gboolean
-SetProcessWorkingSetSize (gpointer process, size_t min, size_t max)
-{
-       WapiHandle_process *process_handle;
-
-       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process))
-               /* This is a pseudo handle, so just fail for now
-                */
-               return FALSE;
-
-       process_handle = lookup_process_handle (process);
-       if (!process_handle) {
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, process);
-               
-               return FALSE;
-       }
-
-       process_handle->min_working_set = min;
-       process_handle->max_working_set = max;
-       
-       return TRUE;
-}
-
-
-gboolean
-TerminateProcess (gpointer process, gint32 exitCode)
-{
-#if defined(HAVE_KILL)
-       WapiHandle_process *process_handle;
-       int signo;
-       int ret;
-       pid_t pid;
-       
-       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) {
-               /* This is a pseudo handle */
-               pid = (pid_t)WAPI_HANDLE_TO_PID (process);
-       } else {
-               process_handle = lookup_process_handle (process);
-               if (!process_handle) {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, process);
-                       SetLastError (ERROR_INVALID_HANDLE);
-                       return FALSE;
-               }
-               pid = process_handle->id;
-       }
-
-       signo = (exitCode == -1) ? SIGKILL : SIGTERM;
-       ret = kill (pid, signo);
-       if (ret == -1) {
-               switch (errno) {
-               case EINVAL:
-                       SetLastError (ERROR_INVALID_PARAMETER);
-                       break;
-               case EPERM:
-                       SetLastError (ERROR_ACCESS_DENIED);
-                       break;
-               case ESRCH:
-                       SetLastError (ERROR_PROC_NOT_FOUND);
-                       break;
-               default:
-                       SetLastError (ERROR_GEN_FAILURE);
-               }
-       }
-       
-       return (ret == 0);
-#else
-       g_error ("kill() is not supported by this platform");
-       return FALSE;
-#endif
-}
-
-guint32
-GetPriorityClass (gpointer process)
-{
-#ifdef HAVE_GETPRIORITY
-       WapiHandle_process *process_handle;
-       int ret;
-       pid_t pid;
-       
-       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) {
-               /* This is a pseudo handle */
-               pid = (pid_t)WAPI_HANDLE_TO_PID (process);
-       } else {
-               process_handle = lookup_process_handle (process);
-               if (!process_handle) {
-                       SetLastError (ERROR_INVALID_HANDLE);
-                       return FALSE;
-               }
-               pid = process_handle->id;
-       }
-
-       errno = 0;
-       ret = getpriority (PRIO_PROCESS, pid);
-       if (ret == -1 && errno != 0) {
-               switch (errno) {
-               case EPERM:
-               case EACCES:
-                       SetLastError (ERROR_ACCESS_DENIED);
-                       break;
-               case ESRCH:
-                       SetLastError (ERROR_PROC_NOT_FOUND);
-                       break;
-               default:
-                       SetLastError (ERROR_GEN_FAILURE);
-               }
-               return FALSE;
-       }
-
-       if (ret == 0)
-               return NORMAL_PRIORITY_CLASS;
-       else if (ret < -15)
-               return REALTIME_PRIORITY_CLASS;
-       else if (ret < -10)
-               return HIGH_PRIORITY_CLASS;
-       else if (ret < 0)
-               return ABOVE_NORMAL_PRIORITY_CLASS;
-       else if (ret > 10)
-               return IDLE_PRIORITY_CLASS;
-       else if (ret > 0)
-               return BELOW_NORMAL_PRIORITY_CLASS;
-
-       return NORMAL_PRIORITY_CLASS;
-#else
-       SetLastError (ERROR_NOT_SUPPORTED);
-       return 0;
-#endif
-}
-
-gboolean
-SetPriorityClass (gpointer process, guint32  priority_class)
-{
-#ifdef HAVE_SETPRIORITY
-       WapiHandle_process *process_handle;
-       int ret;
-       int prio;
-       pid_t pid;
-       
-       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) {
-               /* This is a pseudo handle */
-               pid = (pid_t)WAPI_HANDLE_TO_PID (process);
-       } else {
-               process_handle = lookup_process_handle (process);
-               if (!process_handle) {
-                       SetLastError (ERROR_INVALID_HANDLE);
-                       return FALSE;
-               }
-               pid = process_handle->id;
-       }
-
-       switch (priority_class) {
-       case IDLE_PRIORITY_CLASS:
-               prio = 19;
-               break;
-       case BELOW_NORMAL_PRIORITY_CLASS:
-               prio = 10;
-               break;
-       case NORMAL_PRIORITY_CLASS:
-               prio = 0;
-               break;
-       case ABOVE_NORMAL_PRIORITY_CLASS:
-               prio = -5;
-               break;
-       case HIGH_PRIORITY_CLASS:
-               prio = -11;
-               break;
-       case REALTIME_PRIORITY_CLASS:
-               prio = -20;
-               break;
-       default:
-               SetLastError (ERROR_INVALID_PARAMETER);
-               return FALSE;
-       }
-
-       ret = setpriority (PRIO_PROCESS, pid, prio);
-       if (ret == -1) {
-               switch (errno) {
-               case EPERM:
-               case EACCES:
-                       SetLastError (ERROR_ACCESS_DENIED);
-                       break;
-               case ESRCH:
-                       SetLastError (ERROR_PROC_NOT_FOUND);
-                       break;
-               default:
-                       SetLastError (ERROR_GEN_FAILURE);
-               }
-       }
-
-       return ret == 0;
-#else
-       SetLastError (ERROR_NOT_SUPPORTED);
-       return FALSE;
-#endif
-}
-
-static void
-mono_processes_cleanup (void)
-{
-       struct MonoProcess *mp;
-       struct MonoProcess *prev = NULL;
-       GSList *finished = NULL;
-       GSList *l;
-       gpointer unref_handle;
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s", __func__);
-
-       /* Ensure we're not in here in multiple threads at once, nor recursive. */
-       if (InterlockedCompareExchange (&mono_processes_cleaning_up, 1, 0) != 0)
-               return;
-
-       for (mp = mono_processes; mp; mp = mp->next) {
-               if (mp->pid == 0 && mp->handle) {
-                       /* This process has exited and we need to remove the artifical ref
-                        * on the handle */
-                       mono_os_mutex_lock (&mono_processes_mutex);
-                       unref_handle = mp->handle;
-                       mp->handle = NULL;
-                       mono_os_mutex_unlock (&mono_processes_mutex);
-                       if (unref_handle)
-                               mono_w32handle_unref (unref_handle);
-               }
-       }
-
-       /*
-        * Remove processes which exited from the mono_processes list.
-        * We need to synchronize with the sigchld handler here, which runs
-        * asynchronously. The handler requires that the mono_processes list
-        * remain valid.
-        */
-       mono_os_mutex_lock (&mono_processes_mutex);
-
-       mp = mono_processes;
-       while (mp) {
-               if (mp->handle_count == 0 && mp->freeable) {
-                       /*
-                        * Unlink the entry.
-                        * This code can run parallel with the sigchld handler, but the
-                        * modifications it makes are safe.
-                        */
-                       if (mp == mono_processes)
-                               mono_processes = mp->next;
-                       else
-                               prev->next = mp->next;
-                       finished = g_slist_prepend (finished, mp);
-
-                       mp = mp->next;
-               } else {
-                       prev = mp;
-                       mp = mp->next;
-               }
-       }
-
-       mono_memory_barrier ();
-
-       for (l = finished; l; l = l->next) {
-               /*
-                * All the entries in the finished list are unlinked from mono_processes, and
-                * they have the 'finished' flag set, which means the sigchld handler is done
-                * accessing them.
-                */
-               mp = (MonoProcess *)l->data;
-               mono_os_sem_destroy (&mp->exit_sem);
-               g_free (mp);
-       }
-       g_slist_free (finished);
-
-       mono_os_mutex_unlock (&mono_processes_mutex);
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s done", __func__);
-
-       InterlockedDecrement (&mono_processes_cleaning_up);
-}
-
-static void
-process_close (gpointer handle, gpointer data)
-{
-       WapiHandle_process *process_handle;
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s", __func__);
-
-       process_handle = (WapiHandle_process *) data;
-       g_free (process_handle->proc_name);
-       process_handle->proc_name = NULL;
-       if (process_handle->mono_process)
-               InterlockedDecrement (&process_handle->mono_process->handle_count);
-       mono_processes_cleanup ();
-}
-
-static void process_details (gpointer data)
-{
-       WapiHandle_process *process_handle = (WapiHandle_process *) data;
-       g_print ("id: %d, exited: %s, exitstatus: %d",
-               process_handle->id, process_handle->exited ? "true" : "false", process_handle->exitstatus);
-}
-
-static const gchar* process_typename (void)
-{
-       return "Process";
-}
-
-static gsize process_typesize (void)
-{
-       return sizeof (WapiHandle_process);
-}
-
-#if HAVE_SIGACTION
-MONO_SIGNAL_HANDLER_FUNC (static, mono_sigchld_signal_handler, (int _dummy, siginfo_t *info, void *context))
-{
-       int status;
-       int pid;
-       struct MonoProcess *p;
-
-       do {
-               do {
-                       pid = waitpid (-1, &status, WNOHANG);
-               } while (pid == -1 && errno == EINTR);
-
-               if (pid <= 0)
-                       break;
-
-               /*
-                * This can run concurrently with the code in the rest of this module.
-                */
-               for (p = mono_processes; p; p = p->next) {
-                       if (p->pid == pid) {
-                               break;
-                       }
-               }
-               if (p) {
-                       p->pid = 0; /* this pid doesn't exist anymore, clear it */
-                       p->status = status;
-                       mono_os_sem_post (&p->exit_sem);
-                       mono_memory_barrier ();
-                       /* Mark this as freeable, the pointer becomes invalid afterwards */
-                       p->freeable = TRUE;
-               }
-       } while (1);
-}
-
-#endif
-
-static void
-process_add_sigchld_handler (void)
-{
-#if HAVE_SIGACTION
-       struct sigaction sa;
-
-       sa.sa_sigaction = mono_sigchld_signal_handler;
-       sigemptyset (&sa.sa_mask);
-       sa.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
-       g_assert (sigaction (SIGCHLD, &sa, &previous_chld_sa) != -1);
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "Added SIGCHLD handler");
-#endif
-}
-
-static guint32
-process_wait (gpointer handle, guint32 timeout, gboolean *alerted)
-{
-       WapiHandle_process *process_handle;
-       pid_t pid G_GNUC_UNUSED, ret;
-       int status;
-       gint64 start, now;
-       struct MonoProcess *mp;
-
-       /* FIXME: We can now easily wait on processes that aren't our own children,
-        * but WaitFor*Object won't call us for pseudo handles. */
-       g_assert ((GPOINTER_TO_UINT (handle) & _WAPI_PROCESS_UNHANDLED) != _WAPI_PROCESS_UNHANDLED);
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u)", __func__, handle, timeout);
-
-       if (alerted)
-               *alerted = FALSE;
-
-       process_handle = lookup_process_handle (handle);
-       if (!process_handle) {
-               g_warning ("%s: error looking up process handle %p", __func__, handle);
-               return WAIT_FAILED;
-       }
-
-       if (process_handle->exited) {
-               /* We've already done this one */
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): Process already exited", __func__, handle, timeout);
-               return WAIT_OBJECT_0;
-       }
-
-       pid = process_handle->id;
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): PID: %d", __func__, handle, timeout, pid);
-
-       /* We don't need to lock mono_processes here, the entry
-        * has a handle_count > 0 which means it will not be freed. */
-       mp = process_handle->mono_process;
-       if (!mp) {
-               pid_t res;
-
-               if (pid == mono_process_current_pid ()) {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): waiting on current process", __func__, handle, timeout);
-                       return WAIT_TIMEOUT;
-               }
-
-               /* This path is used when calling Process.HasExited, so
-                * it is only used to poll the state of the process, not
-                * to actually wait on it to exit */
-               g_assert (timeout == 0);
-
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): waiting on non-child process", __func__, handle, timeout);
-
-               res = waitpid (pid, &status, WNOHANG);
-               if (res == 0) {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): non-child process WAIT_TIMEOUT", __func__, handle, timeout);
-                       return WAIT_TIMEOUT;
-               }
-               if (res > 0) {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): non-child process waited successfully", __func__, handle, timeout);
-                       return WAIT_OBJECT_0;
-               }
-
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): non-child process WAIT_FAILED, error : %s (%d))", __func__, handle, timeout, g_strerror (errno), errno);
-               return WAIT_FAILED;
-       }
-
-       start = mono_msec_ticks ();
-       now = start;
-
-       while (1) {
-               if (timeout != INFINITE) {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): waiting on semaphore for %li ms...", 
-                                   __func__, handle, timeout, (long)(timeout - (now - start)));
-                       ret = mono_os_sem_timedwait (&mp->exit_sem, (timeout - (now - start)), alerted ? MONO_SEM_FLAGS_ALERTABLE : MONO_SEM_FLAGS_NONE);
-               } else {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): waiting on semaphore forever...", 
-                                  __func__, handle, timeout);
-                       ret = mono_os_sem_wait (&mp->exit_sem, alerted ? MONO_SEM_FLAGS_ALERTABLE : MONO_SEM_FLAGS_NONE);
-               }
-
-               if (ret == MONO_SEM_TIMEDWAIT_RET_SUCCESS) {
-                       /* Success, process has exited */
-                       mono_os_sem_post (&mp->exit_sem);
-                       break;
-               }
-
-               if (ret == MONO_SEM_TIMEDWAIT_RET_TIMEDOUT) {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): WAIT_TIMEOUT (timeout = 0)", __func__, handle, timeout);
-                       return WAIT_TIMEOUT;
-               }
-
-               now = mono_msec_ticks ();
-               if (now - start >= timeout) {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): WAIT_TIMEOUT", __func__, handle, timeout);
-                       return WAIT_TIMEOUT;
-               }
-               
-               if (alerted && ret == MONO_SEM_TIMEDWAIT_RET_ALERTED) {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): WAIT_IO_COMPLETION", __func__, handle, timeout);
-                       *alerted = TRUE;
-                       return WAIT_IO_COMPLETION;
-               }
-       }
-
-       /* Process must have exited */
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): Waited successfully", __func__, handle, timeout);
-
-       status = mp ? mp->status : 0;
-       if (WIFSIGNALED (status))
-               process_handle->exitstatus = 128 + WTERMSIG (status);
-       else
-               process_handle->exitstatus = WEXITSTATUS (status);
-       _wapi_time_t_to_filetime (time (NULL), &process_handle->exit_time);
-
-       process_handle->exited = TRUE;
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): Setting pid %d signalled, exit status %d",
-                  __func__, handle, timeout, process_handle->id, process_handle->exitstatus);
-
-       mono_w32handle_set_signal_state (handle, TRUE, TRUE);
-
-       return WAIT_OBJECT_0;
-}
-
-void
-wapi_processes_cleanup (void)
-{
-       g_free (cli_launcher);
-}
diff --git a/mono/io-layer/processes.h b/mono/io-layer/processes.h
deleted file mode 100644 (file)
index c4da3ec..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * processes.h:  Process handles
- *
- * Author:
- *     Dick Porter (dick@ximian.com)
- *
- * (C) 2002 Ximian, Inc.
- */
-
-#ifndef _WAPI_PROCESSES_H_
-#define _WAPI_PROCESSES_H_
-
-#include <sys/types.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <glib.h>
-
-#include <mono/io-layer/access.h>
-#include <mono/io-layer/versioninfo.h>
-
-G_BEGIN_DECLS
-
-typedef enum {
-       STARTF_USESHOWWINDOW=0x001,
-       STARTF_USESIZE=0x002,
-       STARTF_USEPOSITION=0x004,
-       STARTF_USECOUNTCHARS=0x008,
-       STARTF_USEFILLATTRIBUTE=0x010,
-       STARTF_RUNFULLSCREEN=0x020,
-       STARTF_FORCEONFEEDBACK=0x040,
-       STARTF_FORCEOFFFEEDBACK=0x080,
-       STARTF_USESTDHANDLES=0x100
-} WapiStartupFlags;
-
-
-typedef struct _WapiStartupInfo WapiStartupInfo;
-
-struct _WapiStartupInfo 
-{
-       guint32 cb;
-       guchar *lpReserved;
-       guchar *lpDesktop;
-       guchar *lpTitle;
-       guint32 dwX;
-       guint32 dwY;
-       guint32 dwXSize;
-       guint32 dwYSize;
-       guint32 dwXCountChars;
-       guint32 dwYCountChars;
-       guint32 dwFillAttribute;
-       WapiStartupFlags dwFlags;
-       guint16 wShowWindow;
-       guint16 cbReserved2;
-       guint8 *lpReserved2;
-       gpointer hStdInput;
-       gpointer hStdOutput;
-       gpointer hStdError;
-};
-
-typedef struct _WapiProcessInformation WapiProcessInformation;
-
-struct _WapiProcessInformation 
-{
-       gpointer hProcess;
-       gpointer hThread;
-       guint32 dwProcessId;
-       guint32 dwThreadId;
-};
-
-typedef enum {
-       SEE_MASK_CLASSNAME      = 0x01,
-       SEE_MASK_CLASSKEY       = 0x03,
-       SEE_MASK_IDLIST         = 0x04,
-       SEE_MASK_INVOKEIDLIST   = 0x0c,
-       SEE_MASK_ICON           = 0x10,
-       SEE_MASK_HOTKEY         = 0x20,
-       SEE_MASK_NOCLOSEPROCESS = 0x40,
-       SEE_MASK_CONNECTNETDRV  = 0x80,
-       SEE_MASK_FLAG_DDEWAIT   = 0x100,
-       SEE_MASK_DOENVSUBST     = 0x200,
-       SEE_MASK_FLAG_NO_UI     = 0x400,
-       SEE_MASK_NO_CONSOLE     = 0x8000,
-       SEE_MASK_UNICODE        = 0x10000,
-       SEE_MASK_HMONITOR       = 0x200000,
-       /*SEE_MASK_FLAG_LOG_USAGE,*/
-       /*SEE_MASK_NOZONECHECKS,*/
-} WapiShellExecuteInfoFlags;
-
-typedef enum {
-       SW_HIDE = 0,
-       SW_SHOWNORMAL = 1,
-       SW_SHOWMINIMIZED = 2,
-       SW_MAXIMIZE = 3,
-       SW_SHOWMAXIMIZED = 3,
-       SW_SHOWNOACTIVATE = 4,
-       SW_SHOW = 5,
-       SW_MINIMIZE = 6,
-       SW_SHOWMINNOACTIVE = 7,
-       SW_SHOWNA = 8,
-       SW_RESTORE = 9,
-       SW_SHOWDEFAULT = 10,
-} WapiShellExecuteShowFlags;
-
-typedef struct _WapiShellExecuteInfo WapiShellExecuteInfo;
-
-struct _WapiShellExecuteInfo
-{
-       guint32 cbSize;
-       gulong fMask;
-       gpointer hwnd;
-       const gunichar2 *lpVerb;
-       const gunichar2 *lpFile;
-       const gunichar2 *lpParameters;
-       const gunichar2 *lpDirectory;
-       gulong nShow;
-       gpointer hInstApp;
-       gpointer lpIDList;
-       const gunichar2 *lpClass;
-       gpointer hkeyClass;
-       guint32 dwHotKey;
-       union 
-       {
-               gpointer hIcon;
-               gpointer hMonitor;
-       } u;
-       gpointer hProcess;
-};
-
-       
-#define DEBUG_PROCESS 0x00000001
-#define DEBUG_ONLY_THIS_PROCESS 0x00000002
-#define DETACHED_PROCESS 0x00000008
-#define CREATE_NEW_CONSOLE 0x00000010
-#define NORMAL_PRIORITY_CLASS 0x00000020
-#define IDLE_PRIORITY_CLASS 0x00000040
-#define HIGH_PRIORITY_CLASS 0x00000080
-#define REALTIME_PRIORITY_CLASS 0x00000100
-#define CREATE_NEW_PROCESS_GROUP 0x00000200
-#define CREATE_UNICODE_ENVIRONMENT 0x00000400
-#define CREATE_SEPARATE_WOW_VDM 0x00000800
-#define CREATE_SHARED_WOW_VDM 0x00001000
-#define CREATE_FORCEDOS 0x00002000
-#define BELOW_NORMAL_PRIORITY_CLASS 0x00004000
-#define ABOVE_NORMAL_PRIORITY_CLASS 0x00008000
-#define CREATE_BREAKAWAY_FROM_JOB 0x01000000
-#define CREATE_WITH_USERPROFILE 0x02000000
-#define CREATE_DEFAULT_ERROR_MODE 0x04000000
-#define CREATE_NO_WINDOW 0x08000000
-
-#ifdef NEW_STUFF
-#define CREATE_PRESERVE_CODE_AUTHZ_LEVEL find out the value for this one...
-#endif
-
-#define        PROCESS_TERMINATE               0x0001
-#define        PROCESS_CREATE_THREAD           0x0002
-#define        PROCESS_SET_SESSIONID           0x0004
-#define        PROCESS_VM_OPERATION            0x0008
-#define        PROCESS_VM_READ                 0x0010
-#define        PROCESS_VM_WRITE                0x0020
-#define        PROCESS_DUP_HANDLE              0x0040
-#define        PROCESS_CREATE_PROCESS          0x0080
-#define        PROCESS_SET_QUOTA               0x0100
-#define        PROCESS_SET_INFORMATION         0x0200
-#define        PROCESS_QUERY_INFORMATION       0x0400
-#define        PROCESS_ALL_ACCESS              (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xfff)
-
-extern gboolean ShellExecuteEx (WapiShellExecuteInfo *sei);
-extern gboolean CreateProcess (const gunichar2 *appname,
-                              const gunichar2 *cmdline,
-                              WapiSecurityAttributes *process_attrs,
-                              WapiSecurityAttributes *thread_attrs,
-                              gboolean inherit_handles, guint32 create_flags,
-                              gpointer environ, const gunichar2 *cwd,
-                              WapiStartupInfo *startup,
-                              WapiProcessInformation *process_info);
-extern gboolean CreateProcessWithLogonW (const gunichar2 *username,
-                                        const gunichar2 *domain,
-                                        const gunichar2 *password,
-                                        const guint32 logonFlags,
-                                        const gunichar2 *appname,
-                                        const gunichar2 *cmdline,
-                                        guint32 create_flags,
-                                        gpointer environ,
-                                        const gunichar2 *cwd,
-                                        WapiStartupInfo *startup,
-                                        WapiProcessInformation *process_info);
-#define LOGON_WITH_PROFILE 0x00000001
-#define LOGON_NETCREDENTIALS_ONLY 0x00000002
-
-extern gpointer GetCurrentProcess (void);
-extern guint32 GetProcessId (gpointer handle);
-extern gboolean CloseProcess (gpointer handle);
-extern gpointer OpenProcess (guint32 access, gboolean inherit, guint32 pid);
-extern gboolean GetExitCodeProcess (gpointer process, guint32 *code);
-extern gboolean GetProcessTimes (gpointer process, WapiFileTime *create_time,
-                                WapiFileTime *exit_time,
-                                WapiFileTime *kernel_time,
-                                WapiFileTime *user_time);
-extern gboolean EnumProcessModules (gpointer process, gpointer *modules,
-                                   guint32 size, guint32 *needed);
-extern guint32 GetModuleBaseName (gpointer process, gpointer module,
-                                 gunichar2 *basename, guint32 size);
-extern guint32 GetModuleFileNameEx (gpointer process, gpointer module,
-                                   gunichar2 *filename, guint32 size);
-extern gboolean GetModuleInformation (gpointer process, gpointer module,
-                                     WapiModuleInfo *modinfo, guint32 size);
-extern gboolean GetProcessWorkingSetSize (gpointer process, size_t *min,
-                                         size_t *max);
-extern gboolean SetProcessWorkingSetSize (gpointer process, size_t min,
-                                         size_t max);
-
-extern gboolean TerminateProcess (gpointer process, gint32 exitCode);
-
-extern guint32 GetPriorityClass (gpointer process);
-extern gboolean SetPriorityClass (gpointer process, guint32  priority_class);
-
-gchar* wapi_process_get_path (pid_t pid);
-
-void wapi_process_set_cli_launcher (char *path);
-
-G_END_DECLS
-
-#endif /* _WAPI_PROCESSES_H_ */
index 05012d26fbbb505967a484272cb4ed1c99f6bad7..b374973ebc67288c7b5fe9ba35c64c50d1a40856 100644 (file)
@@ -44,7 +44,7 @@
 #include <mono/utils/mono-poll.h>
 #include <mono/utils/mono-once.h>
 #include <mono/utils/mono-logger-internals.h>
-#include <mono/utils/w32handle.h>
+#include <mono/metadata/w32handle.h>
 
 #include <netinet/in.h>
 #include <netinet/tcp.h>
diff --git a/mono/io-layer/timefuncs-private.h b/mono/io-layer/timefuncs-private.h
deleted file mode 100644 (file)
index ff00879..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * timefuncs-private.h:  performance timer and other time private functions
- *
- * Author:
- *     Dick Porter (dick@ximian.com)
- *
- * (C) 2002 Ximian, Inc.
- */
-
-#ifndef _WAPI_TIMEFUNCS_PRIVATE_H_
-#define _WAPI_TIMEFUNCS_PRIVATE_H_
-
-#include <config.h>
-#include <glib.h>
-#include <sys/time.h>
-
-extern void _wapi_time_t_to_filetime (time_t timeval, WapiFileTime *filetime);
-extern void _wapi_guint64_to_filetime (guint64 ticks, WapiFileTime *filetime);
-
-#endif /* _WAPI_TIMEFUNCS_PRIVATE_H_ */
index 0528ae6946df59b7bd1f55f2e07b5062d2f3d8aa..7ec8e4a8ee72a8ae43922dd6cb794c5c2d2e41cf 100644 (file)
@@ -14,7 +14,7 @@
 #include <stdio.h>
 
 #include <mono/io-layer/wapi.h>
-#include <mono/io-layer/timefuncs-private.h>
+#include <mono/io-layer/timefuncs.h>
 #include "mono/utils/mono-time.h"
 
 #undef DEBUG
@@ -27,9 +27,3 @@ void _wapi_time_t_to_filetime (time_t timeval, WapiFileTime *filetime)
        filetime->dwLowDateTime = ticks & 0xFFFFFFFF;
        filetime->dwHighDateTime = ticks >> 32;
 }
-
-void _wapi_guint64_to_filetime (guint64 ticks, WapiFileTime *filetime)
-{
-       filetime->dwLowDateTime = ticks & 0xFFFFFFFF;
-       filetime->dwHighDateTime = ticks >> 32;
-}
index d24800229f22aef11724cd81700cf58fe1ed352b..2b43396931b0db51e8401ad0372c249efaf72e45 100644 (file)
@@ -12,6 +12,8 @@
 
 #include <glib.h>
 
+#include <sys/time.h>
+
 #include "mono/io-layer/wapi.h"
 
 G_BEGIN_DECLS
@@ -30,5 +32,7 @@ typedef struct
 #endif
 } WapiFileTime;
 
+extern void _wapi_time_t_to_filetime (time_t timeval, WapiFileTime *filetime);
+
 G_END_DECLS
 #endif /* _WAPI_TIME_H_ */
index 5176da07ea7f2aa98f284fbf665d6f7d1cd2d629..09fea6b71393162064bcf93ccbe450cdc5246fae 100644 (file)
@@ -70,9 +70,6 @@ typedef WapiFindData WIN32_FIND_DATA;
 typedef WapiFindData *LPWIN32_FIND_DATA;
 typedef WapiFileAttributesData WIN32_FILE_ATTRIBUTE_DATA;
 typedef WapiGetFileExInfoLevels GET_FILEEX_INFO_LEVELS;
-typedef WapiStartupInfo STARTUPINFO;
-typedef WapiStartupInfo *LPSTARTUPINFO;
-typedef WapiProcessInformation PROCESS_INFORMATION;
 typedef WapiFixedFileInfo VS_FIXEDFILEINFO;
 typedef WapiModuleInfo MODULEINFO;
 typedef WapiModuleInfo *LPMODULEINFO;
@@ -102,8 +99,6 @@ typedef WapiImageResourceDirectoryEntry IMAGE_RESOURCE_DIRECTORY_ENTRY;
 typedef WapiImageResourceDirectoryEntry *PIMAGE_RESOURCE_DIRECTORY_ENTRY;
 typedef WapiImageResourceDataEntry IMAGE_RESOURCE_DATA_ENTRY;
 typedef WapiImageResourceDataEntry *PIMAGE_RESOURCE_DATA_ENTRY;
-typedef WapiShellExecuteInfo SHELLEXECUTEINFO;
-typedef WapiShellExecuteInfo *LPSHELLEXECUTEINFO;
 typedef WapiTransmitFileBuffers TRANSMIT_FILE_BUFFERS;
 typedef WapiTransmitFileBuffers *PTRANSMIT_FILE_BUFFERS;
 typedef WapiTransmitFileBuffers *LPTRANSMIT_FILE_BUFFERS;
index aa58ea1614f76dde7cc51478b3cc0a73b7991b40..b7ff4684263846776bd3ff0f2ac346ed23cfcf8d 100644 (file)
@@ -14,7 +14,7 @@
 
 #include <mono/io-layer/wapi.h>
 #include <mono/io-layer/wapi-private.h>
-#include <mono/utils/w32handle.h>
+#include <mono/metadata/w32handle.h>
 
 /**
  * WaitForSingleObjectEx:
index b1fef4b1479361fd065bc19bf43bae631003f823..cbbf5d68203b93857d3da19886db35de93ef873e 100644 (file)
@@ -11,7 +11,7 @@
 #define _WAPI_WAIT_H_
 
 #include "mono/io-layer/status.h"
-#include "mono/utils/w32handle.h"
+#include "mono/metadata/w32handle.h"
 
 G_BEGIN_DECLS
 
index 8b82b609d1976be0cf356e0d13904f970aa8b585..9be764c15218771e3bb46150829b67b85286ca1d 100644 (file)
@@ -26,8 +26,7 @@ extern gboolean _wapi_has_shut_down;
 
 #include <mono/io-layer/io-private.h>
 #include <mono/io-layer/socket-private.h>
-#include <mono/io-layer/process-private.h>
-#include <mono/utils/w32handle.h>
+#include <mono/metadata/w32handle.h>
 
 struct _WapiHandle_shared_ref
 {
index 935d257722557872189afa90b439e60a2d57ff99..783a9f1c4d4e72b1bb1eedd0d183169eefa699d0 100644 (file)
 #define UnlockFile wapi_UnlockFile 
 #define GetVolumeInformation wapi_GetVolumeInformation 
 #define FormatMessage wapi_FormatMessage 
-#define ShellExecuteEx wapi_ShellExecuteEx 
-#define CreateProcess wapi_CreateProcess 
-#define CreateProcessWithLogonW wapi_CreateProcessWithLogonW 
-#define GetCurrentProcess wapi_GetCurrentProcess 
-#define GetProcessId wapi_GetProcessId 
-#define CloseProcess wapi_CloseProcess 
-#define OpenProcess wapi_OpenProcess 
-#define GetExitCodeProcess wapi_GetExitCodeProcess 
-#define GetProcessTimes wapi_GetProcessTimes 
-#define EnumProcessModules wapi_EnumProcessModules 
-#define GetModuleBaseName wapi_GetModuleBaseName 
-#define GetModuleFileNameEx wapi_GetModuleFileNameEx 
-#define GetModuleInformation wapi_GetModuleInformation 
-#define GetProcessWorkingSetSize wapi_GetProcessWorkingSetSize 
-#define SetProcessWorkingSetSize wapi_SetProcessWorkingSetSize 
-#define TerminateProcess wapi_TerminateProcess 
-#define GetPriorityClass wapi_GetPriorityClass 
-#define SetPriorityClass wapi_SetPriorityClass 
 #define ImpersonateLoggedOnUser wapi_ImpersonateLoggedOnUser 
 #define RevertToSelf wapi_RevertToSelf 
 #define WSASetLastError wapi_WSASetLastError
index f1674179d9a194f0d2dcb4d992acbf5bb6926d3c..f162b0bb45cad926593816f8e28366fcfd034dd7 100644 (file)
@@ -3,11 +3,10 @@
 
 #include "io-trace.h"
 #include "io.h"
-#include "process-private.h"
 #include "socket-private.h"
 
 #include "mono/utils/mono-lazy-init.h"
-#include "mono/utils/w32handle.h"
+#include "mono/metadata/w32handle.h"
 
 gboolean _wapi_has_shut_down = FALSE;
 
@@ -15,7 +14,6 @@ void
 wapi_init (void)
 {
        _wapi_io_init ();
-       _wapi_processes_init ();
        _wapi_socket_init ();
 }
 
@@ -26,7 +24,6 @@ wapi_cleanup (void)
        _wapi_has_shut_down = TRUE;
 
        _wapi_error_cleanup ();
-       wapi_processes_cleanup ();
        _wapi_io_cleanup ();
 }
 
@@ -54,19 +51,8 @@ gboolean
 DuplicateHandle (gpointer srcprocess, gpointer src, gpointer targetprocess, gpointer *target,
        guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, guint32 options G_GNUC_UNUSED)
 {
-       if (srcprocess != _WAPI_PROCESS_CURRENT || targetprocess != _WAPI_PROCESS_CURRENT) {
-               /* Duplicating other process's handles is not supported */
-               SetLastError (ERROR_INVALID_HANDLE);
-               return FALSE;
-       }
-
-       if (src == _WAPI_PROCESS_CURRENT) {
-               *target = _wapi_process_duplicate ();
-       } else {
-               mono_w32handle_ref (src);
-               *target = src;
-       }
-
+       mono_w32handle_ref (src);
+       *target = src;
        return TRUE;
 }
 
index c56622ea91c003c548288148cf8c49f9998c22bd..1af86f7712cc71cc9f4bd4dadba60027a8763b65 100644 (file)
 #include <mono/io-layer/types.h>
 #include <mono/io-layer/macros.h>
 #include <mono/io-layer/io.h>
-#include <mono/io-layer/access.h>
 #include <mono/io-layer/context.h>
 #include <mono/io-layer/error.h>
 #include <mono/io-layer/messages.h>
-#include <mono/io-layer/processes.h>
 #include <mono/io-layer/security.h>
 #include <mono/io-layer/sockets.h>
 #include <mono/io-layer/status.h>
index 7e07c2549f5daa42a9d2d83d716f67a7d7875468..a48d586713f751a7f02520017476835819ec8c35 100644 (file)
@@ -10,11 +10,11 @@ win32_sources = \
        marshal-windows-internals.h \
        mono-security-windows.c \
        mono-security-windows-internals.h \
-       process-windows.c \
-       process-windows-internals.h \
        w32mutex-win32.c \
        w32semaphore-win32.c \
        w32event-win32.c \
+       w32process-win32.c \
+       w32process-win32-internals.h \
        socket-io-windows.c
 
 platform_sources = $(win32_sources)
@@ -41,7 +41,13 @@ unix_sources = \
        console-unix.c \
        w32mutex-unix.c \
        w32semaphore-unix.c \
-       w32event-unix.c
+       w32event-unix.c \
+       w32process-unix.c \
+       w32process-unix-internals.h \
+       w32process-unix-osx.c \
+       w32process-unix-bsd.c \
+       w32process-unix-haiku.c \
+       w32process-unix-default.c
 
 platform_sources = $(unix_sources)
 endif
@@ -119,6 +125,8 @@ common_sources = \
        cil-coff.h              \
        class.c                 \
        class-internals.h       \
+       class-inlines.h         \
+       class-accessors.c       \
        cominterop.c            \
        cominterop.h            \
        console-io.h            \
@@ -195,9 +203,9 @@ common_sources = \
        opcodes.c               \
        socket-io.c             \
        socket-io.h             \
-       process.c               \
-       process.h               \
-       process-internals.h \
+       w32process.c            \
+       w32process.h            \
+       w32process-internals.h          \
        profiler.c              \
        profiler-private.h      \
        rand.h                  \
@@ -246,7 +254,9 @@ common_sources = \
        w32semaphore.h  \
        w32event.h      \
        w32handle-namespace.h   \
-       w32handle-namespace.c
+       w32handle-namespace.c   \
+       w32handle.h     \
+       w32handle.c
 
 # These source files have compile time dependencies on GC code
 gc_dependent_sources = \
index e134b8f6120c0e7efc79b24ff23e9203a40bb750..db45a76a95e44a0c7d18d70dcbfc9dec1dc8d5cc 100644 (file)
@@ -68,7 +68,7 @@
 #include <mono/utils/atomic.h>
 #include <mono/utils/mono-memory-model.h>
 #include <mono/utils/mono-threads.h>
-#include <mono/utils/w32handle.h>
+#include <mono/metadata/w32handle.h>
 #ifdef HOST_WIN32
 #include <direct.h>
 #endif
@@ -84,7 +84,7 @@
  * Changes which are already detected at runtime, like the addition
  * of icalls, do not require an increment.
  */
-#define MONO_CORLIB_VERSION 160
+#define MONO_CORLIB_VERSION 162
 
 typedef struct
 {
@@ -2480,13 +2480,13 @@ mono_domain_unload (MonoDomain *domain)
        mono_domain_try_unload (domain, &exc);
 }
 
-static guint32
-guarded_wait (HANDLE handle, guint32 timeout, gboolean alertable)
+static MonoThreadInfoWaitRet
+guarded_wait (MonoThreadHandle *thread_handle, guint32 timeout, gboolean alertable)
 {
-       guint32 result;
+       MonoThreadInfoWaitRet result;
 
        MONO_ENTER_GC_SAFE;
-       result = WaitForSingleObjectEx (handle, timeout, alertable);
+       result = mono_thread_info_wait_one_handle (thread_handle, timeout, alertable);
        MONO_EXIT_GC_SAFE;
 
        return result;
@@ -2515,7 +2515,7 @@ void
 mono_domain_try_unload (MonoDomain *domain, MonoObject **exc)
 {
        MonoError error;
-       HANDLE thread_handle;
+       MonoThreadHandle *thread_handle;
        MonoAppDomainState prev_state;
        MonoMethod *method;
        unload_data *thread_data;
@@ -2582,7 +2582,7 @@ mono_domain_try_unload (MonoDomain *domain, MonoObject **exc)
                return;
 
        /* Wait for the thread */       
-       while (!thread_data->done && guarded_wait (thread_handle, INFINITE, TRUE) == WAIT_IO_COMPLETION) {
+       while (!thread_data->done && guarded_wait (thread_handle, INFINITE, TRUE) == MONO_THREAD_INFO_WAIT_RET_ALERTED) {
                if (mono_thread_internal_has_appdomain_ref (mono_thread_internal_current (), domain) && (mono_thread_interruption_requested ())) {
                        /* The unload thread tries to abort us */
                        /* The icall wrapper will execute the abort */
index 209e4ab4f988192fe280953fe7d5017c547d56b3..cae45aa64abde017a5223bcb5ecbc25dda2fa3da 100644 (file)
@@ -22,6 +22,7 @@
 #include "object-internals.h"
 #include <mono/metadata/loader.h>
 #include <mono/metadata/tabledefs.h>
+#include <mono/metadata/custom-attrs-internals.h>
 #include <mono/metadata/metadata-internals.h>
 #include <mono/metadata/profiler-private.h>
 #include <mono/metadata/class-internals.h>
@@ -205,8 +206,6 @@ static GSList *loaded_assembly_bindings = NULL;
 
 /* Class lazy loading functions */
 static GENERATE_TRY_GET_CLASS_WITH_CACHE (internals_visible, System.Runtime.CompilerServices, InternalsVisibleToAttribute)
-static GENERATE_TRY_GET_CLASS_WITH_CACHE (reference_assembly, System.Runtime.CompilerServices, ReferenceAssemblyAttribute)
-
 static MonoAssembly*
 mono_assembly_invoke_search_hook_internal (MonoAssemblyName *aname, MonoAssembly *requesting, gboolean refonly, gboolean postload);
 static MonoAssembly*
@@ -1768,7 +1767,7 @@ mono_assembly_load_friends (MonoAssembly* ass)
        if (ass->friend_assembly_names_inited)
                return;
 
-       attrs = mono_custom_attrs_from_assembly_checked (ass, &error);
+       attrs = mono_custom_attrs_from_assembly_checked (ass, FALSE, &error);
        mono_error_assert_ok (&error);
        if (!attrs) {
                mono_assemblies_lock ();
@@ -1828,6 +1827,24 @@ mono_assembly_load_friends (MonoAssembly* ass)
        mono_assemblies_unlock ();
 }
 
+struct HasReferenceAssemblyAttributeIterData {
+       gboolean has_attr;
+};
+
+static gboolean
+has_reference_assembly_attribute_iterator (MonoImage *image, guint32 typeref_scope_token, const char *nspace, const char *name, guint32 method_token, gpointer user_data)
+{
+       gboolean stop_scanning = FALSE;
+       struct HasReferenceAssemblyAttributeIterData *iter_data = (struct HasReferenceAssemblyAttributeIterData*)user_data;
+
+       if (!strcmp (name, "ReferenceAssemblyAttribute") && !strcmp (nspace, "System.Runtime.CompilerServices")) {
+               /* Note we don't check the assembly name, same as coreCLR. */
+               iter_data->has_attr = TRUE;
+               stop_scanning = TRUE;
+       }
+
+       return stop_scanning;
+}
 
 /**
  * mono_assembly_has_reference_assembly_attribute:
@@ -1842,24 +1859,16 @@ mono_assembly_has_reference_assembly_attribute (MonoAssembly *assembly, MonoErro
 {
        mono_error_init (error);
 
-/* TODO: mono_custom_attrs_from_assembly_checked returns NULL if a
- * single assembly is missing.  The custom attr we want is from
- * corlib, however, so we need a more robust version that doesn't care
- * about missing attributes.
- */
-#if 0
-       MonoCustomAttrInfo *attrs = mono_custom_attrs_from_assembly_checked (assembly, error);
-       return_val_if_nok (error, FALSE);
-       if (!attrs)
-               return FALSE;
-       MonoClass *ref_asm_class = mono_class_try_get_reference_assembly_class ();
-       g_assert (ref_asm_class != NULL && ref_asm_class != mono_defaults.object_class && !strcmp(ref_asm_class->name, "ReferenceAssemblyAttribute") );
-       gboolean result = mono_custom_attrs_has_attr (attrs, ref_asm_class);
-       mono_custom_attrs_free (attrs);
-       return result;
-#else
-       return FALSE;
-#endif
+       /*
+        * This might be called during assembly loading, so do everything using the low-level
+        * metadata APIs.
+        */
+
+       struct HasReferenceAssemblyAttributeIterData iter_data = { FALSE };
+
+       mono_assembly_metadata_foreach_custom_attr (assembly, &has_reference_assembly_attribute_iterator, &iter_data);
+
+       return iter_data.has_attr;
 }
 
 /**
@@ -1981,24 +1990,6 @@ mono_assembly_load_from_full (MonoImage *image, const char*fname,
                }
        }
 
-       mono_assemblies_lock ();
-
-       if (image->assembly) {
-               /* 
-                * This means another thread has already loaded the assembly, but not yet
-                * called the load hooks so the search hook can't find the assembly.
-                */
-               mono_assemblies_unlock ();
-               ass2 = image->assembly;
-               g_free (ass);
-               g_free (base_dir);
-               mono_image_close (image);
-               *status = MONO_IMAGE_OK;
-               return ass2;
-       }
-
-       mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Prepared to set up assembly '%s' (%s)", ass->aname.name, image->name);
-
        /* We need to check for ReferenceAssmeblyAttribute before we
         * mark the assembly as loaded and before we fire the load
         * hook. Otherwise mono_domain_fire_assembly_load () in
@@ -2006,17 +1997,9 @@ mono_assembly_load_from_full (MonoImage *image, const char*fname,
         * this image and we won't be able to look for a different
         * candidate. */
 
-       if (!refonly && strcmp (ass->aname.name, "mscorlib") != 0) {
-               /* Don't check for reference assmebly attribute for
-                * corlib here because if corlib isn't loaded yet,
-                * it's too early to set up the
-                * ReferenceAssemblyAttribute class.  We check that
-                * we're not running with a reference corlib in
-                * mono_init_internal().
-                */
+       if (!refonly) {
                MonoError refasm_error;
                if (mono_assembly_has_reference_assembly_attribute (ass, &refasm_error)) {
-                       mono_assemblies_unlock ();
                        mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Image for assembly '%s' (%s) has ReferenceAssemblyAttribute, skipping", ass->aname.name, image->name);
                        g_free (ass);
                        g_free (base_dir);
@@ -2027,6 +2010,24 @@ mono_assembly_load_from_full (MonoImage *image, const char*fname,
                mono_error_cleanup (&refasm_error);
        }
 
+       mono_assemblies_lock ();
+
+       if (image->assembly) {
+               /*
+                * This means another thread has already loaded the assembly, but not yet
+                * called the load hooks so the search hook can't find the assembly.
+                */
+               mono_assemblies_unlock ();
+               ass2 = image->assembly;
+               g_free (ass);
+               g_free (base_dir);
+               mono_image_close (image);
+               *status = MONO_IMAGE_OK;
+               return ass2;
+       }
+
+       mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Prepared to set up assembly '%s' (%s)", ass->aname.name, image->name);
+
        image->assembly = ass;
 
        loaded_assemblies = g_list_prepend (loaded_assemblies, ass);
index 01d208c2ea275de80efa69f0f93dce1fe036edbf..2c4372ba4b493fed8b441d6704c31c88a713da4c 100644 (file)
@@ -94,7 +94,7 @@ static char *ipc_filename;
 
 static char *server_uri;
 
-static HANDLE receiver_thread_handle;
+static MonoThreadHandle *receiver_thread_handle;
 
 static gboolean stop_receiver_thread;
 
@@ -260,7 +260,7 @@ mono_attach_cleanup (void)
 
        /* Wait for the receiver thread to exit */
        if (receiver_thread_handle)
-               WaitForSingleObjectEx (receiver_thread_handle, 0, FALSE);
+               mono_thread_info_wait_one_handle (receiver_thread_handle, 0, FALSE);
 }
 
 static int
index 2c648c85da6d7bf8bb36a165c5931bafe013fe3a..0d47d88beda989a173d99301957aa1dc1f0abd86 100644 (file)
@@ -1115,7 +1115,7 @@ create_allocator (int atype, int tls_key, gboolean slowpath)
 static MonoMethod* alloc_method_cache [ATYPE_NUM];
 static MonoMethod* slowpath_alloc_method_cache [ATYPE_NUM];
 
-static G_GNUC_UNUSED gboolean
+gboolean
 mono_gc_is_critical_method (MonoMethod *method)
 {
        int i;
@@ -1234,7 +1234,7 @@ mono_gc_get_write_barrier (void)
 
 #else
 
-static G_GNUC_UNUSED gboolean
+gboolean
 mono_gc_is_critical_method (MonoMethod *method)
 {
        return FALSE;
diff --git a/mono/metadata/class-accessors.c b/mono/metadata/class-accessors.c
new file mode 100644 (file)
index 0000000..fe793dd
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#include <mono/metadata/class-internals.h>
+#include <mono/metadata/tabledefs.h>
+
+
+/* Accessors based on class kind*/
+
+/*
+* mono_class_get_generic_class:
+*
+*   Return the MonoGenericClass of @klass, which MUST be a generic instance.
+*/
+MonoGenericClass*
+mono_class_get_generic_class (MonoClass *klass)
+{
+       g_assert (mono_class_is_ginst (klass));
+       return ((MonoClassGenericInst*)klass)->generic_class;
+}
+
+/*
+* mono_class_try_get_generic_class:
+*
+*   Return the MonoGenericClass if @klass is a ginst, NULL otherwise
+*/
+MonoGenericClass*
+mono_class_try_get_generic_class (MonoClass *klass)
+{
+       if (mono_class_is_ginst (klass))
+               return ((MonoClassGenericInst*)klass)->generic_class;
+       return NULL;
+}
+
+/**
+ * mono_class_get_flags:
+ * @klass: the MonoClass to act on
+ *
+ * Return the TypeAttributes flags of @klass.
+ * See the TYPE_ATTRIBUTE_* definitions on tabledefs.h for the different values.
+ *
+ * Returns: The type flags
+ */
+guint32
+mono_class_get_flags (MonoClass *klass)
+{
+       switch (klass->class_kind) {
+       case MONO_CLASS_DEF:
+       case MONO_CLASS_GTD:
+               return ((MonoClassDef*)klass)->flags;
+       case MONO_CLASS_GINST:
+               return mono_class_get_flags (((MonoClassGenericInst*)klass)->generic_class->container_class);
+       case MONO_CLASS_GPARAM:
+               return TYPE_ATTRIBUTE_PUBLIC;
+       case MONO_CLASS_ARRAY:
+               /* all arrays are marked serializable and sealed, bug #42779 */
+               return TYPE_ATTRIBUTE_CLASS | TYPE_ATTRIBUTE_SERIALIZABLE | TYPE_ATTRIBUTE_SEALED | TYPE_ATTRIBUTE_PUBLIC;
+       case MONO_CLASS_POINTER:
+               return TYPE_ATTRIBUTE_CLASS | (mono_class_get_flags (klass->element_class) & TYPE_ATTRIBUTE_VISIBILITY_MASK);
+       }
+       g_assert_not_reached ();
+}
+
+void
+mono_class_set_flags (MonoClass *klass, guint32 flags)
+{
+       g_assert (klass->class_kind == MONO_CLASS_DEF || klass->class_kind == MONO_CLASS_GTD);
+       ((MonoClassDef*)klass)->flags = flags;
+}
+
+/*
+ * mono_class_get_generic_container:
+ *
+ *   Return the generic container of KLASS which should be a generic type definition.
+ */
+MonoGenericContainer*
+mono_class_get_generic_container (MonoClass *klass)
+{
+       g_assert (mono_class_is_gtd (klass));
+
+       return ((MonoClassGtd*)klass)->generic_container;
+}
+
+MonoGenericContainer*
+mono_class_try_get_generic_container (MonoClass *klass)
+{
+       if (mono_class_is_gtd (klass))
+               return ((MonoClassGtd*)klass)->generic_container;
+       return NULL;
+}
+
+
+void
+mono_class_set_generic_container (MonoClass *klass, MonoGenericContainer *container)
+{
+       g_assert (mono_class_is_gtd (klass));
+
+       ((MonoClassGtd*)klass)->generic_container = container;
+}
+
+/*
+ * mono_class_get_first_method_idx:
+ *
+ *   Return the table index of the first method for metadata classes.
+ */
+guint32
+mono_class_get_first_method_idx (MonoClass *klass)
+{
+       g_assert (mono_class_has_static_metadata (klass));
+
+       return ((MonoClassDef*)klass)->first_method_idx;
+}
+
+void
+mono_class_set_first_method_idx (MonoClass *klass, guint32 idx)
+{
+       g_assert (mono_class_has_static_metadata (klass));
+
+       ((MonoClassDef*)klass)->first_method_idx = idx;
+}
+
+guint32
+mono_class_get_first_field_idx (MonoClass *klass)
+{
+       if (mono_class_is_ginst (klass))
+               return mono_class_get_first_field_idx (mono_class_get_generic_class (klass)->container_class);
+
+       g_assert (mono_class_has_static_metadata (klass));
+
+       return ((MonoClassDef*)klass)->first_field_idx;
+}
+
+void
+mono_class_set_first_field_idx (MonoClass *klass, guint32 idx)
+{
+       g_assert (mono_class_has_static_metadata (klass));
+
+       ((MonoClassDef*)klass)->first_field_idx = idx;
+}
diff --git a/mono/metadata/class-inlines.h b/mono/metadata/class-inlines.h
new file mode 100644 (file)
index 0000000..2e884ba
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#ifndef __MONO_METADATA_CLASS_INLINES_H__
+#define __MONO_METADATA_CLASS_INLINES_H__
+
+#include <mono/metadata/class-internals.h>
+#include <mono/metadata/tabledefs.h>
+
+static inline gboolean
+mono_class_is_def (MonoClass *klass)
+{
+       return klass->class_kind == MONO_CLASS_DEF;
+}
+
+static inline gboolean
+mono_class_is_gtd (MonoClass *klass)
+{
+       return klass->class_kind == MONO_CLASS_GTD;
+}
+
+static inline gboolean
+mono_class_is_ginst (MonoClass *klass)
+{
+       return klass->class_kind == MONO_CLASS_GINST;
+}
+
+static inline gboolean
+mono_class_is_gparam (MonoClass *klass)
+{
+       return klass->class_kind == MONO_CLASS_GPARAM;
+}
+
+static inline gboolean
+mono_class_is_array (MonoClass *klass)
+{
+       return klass->class_kind == MONO_CLASS_ARRAY;
+}
+
+static inline gboolean
+mono_class_is_pointer (MonoClass *klass)
+{
+       return klass->class_kind == MONO_CLASS_POINTER;
+}
+
+static inline gboolean
+mono_class_is_abstract (MonoClass *klass)
+{
+       return mono_class_get_flags (klass) & TYPE_ATTRIBUTE_ABSTRACT;
+}
+
+static inline gboolean
+mono_class_is_interface (MonoClass *klass)
+{
+       return mono_class_get_flags (klass) & TYPE_ATTRIBUTE_INTERFACE;
+}
+
+static inline gboolean
+mono_class_is_sealed (MonoClass *klass)
+{
+       return mono_class_get_flags (klass) & TYPE_ATTRIBUTE_SEALED;
+}
+
+static inline gboolean
+mono_class_is_before_field_init (MonoClass *klass)
+{
+       return mono_class_get_flags (klass) & TYPE_ATTRIBUTE_BEFORE_FIELD_INIT;
+}
+
+static inline gboolean
+mono_class_is_auto_layout (MonoClass *klass)
+{
+       return (mono_class_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT;
+}
+
+static inline gboolean
+mono_class_is_explicit_layout (MonoClass *klass)
+{
+       return (mono_class_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT;
+}
+
+static inline gboolean
+mono_class_is_public (MonoClass *klass)
+{
+       return mono_class_get_flags (klass) & TYPE_ATTRIBUTE_PUBLIC;
+}
+
+static inline gboolean
+mono_class_has_static_metadata (MonoClass *klass)
+{
+       return klass->type_token && !klass->image->dynamic && !mono_class_is_ginst (klass);
+}
+
+#endif
index b2af4f795564c8bbd8231d00b2470a4b46250465..0c14ec3b04236557fbc37d94da1ab3f042768355 100644 (file)
@@ -16,7 +16,7 @@
 
 #define MONO_CLASS_IS_ARRAY(c) ((c)->rank)
 
-#define MONO_CLASS_HAS_STATIC_METADATA(klass) ((klass)->type_token && !(klass)->image->dynamic && !(klass)->generic_class)
+#define MONO_CLASS_HAS_STATIC_METADATA(klass) ((klass)->type_token && !(klass)->image->dynamic && !mono_class_is_ginst (klass))
 
 #define MONO_DEFAULT_SUPERTABLE_SIZE 6
 
@@ -256,6 +256,15 @@ typedef struct {
        GList      *nested_classes;
 } MonoClassExt;
 
+typedef enum {
+       MONO_CLASS_DEF = 1, /* non-generic type */
+       MONO_CLASS_GTD, /* generic type definition */
+       MONO_CLASS_GINST, /* generic instantiation */
+       MONO_CLASS_GPARAM, /* generic parameter */
+       MONO_CLASS_ARRAY, /* vector or array, bounded or not */
+       MONO_CLASS_POINTER, /* pointer of function pointer*/
+} MonoTypeKind;
+
 struct _MonoClass {
        /* element class for arrays and enum basetype for enums */
        MonoClass *element_class; 
@@ -272,8 +281,6 @@ struct _MonoClass {
        int        instance_size; /* object instance size */
 
        guint inited          : 1;
-       /* We use init_pending to detect cyclic calls to mono_class_init */
-       guint init_pending    : 1;
 
        /* A class contains static and non static data. Static data can be
         * of the same type as the class itselfs, but it does not influence
@@ -317,10 +324,9 @@ struct _MonoClass {
        guint nested_classes_inited : 1; /* Whenever nested_class is initialized */
 
        /* next byte*/
+       guint class_kind : 3; /* One of the values from MonoTypeKind */
        guint interfaces_inited : 1; /* interfaces is initialized */
        guint simd_type : 1; /* class is a simd intrinsic type */
-       guint is_generic : 1; /* class is a generic type definition */
-       guint is_inflated : 1; /* class is a generic instance */
        guint has_finalize_inited    : 1; /* has_finalize is initialized */
        guint fields_inited : 1; /* setup_fields () has finished */
        guint has_failure : 1; /* See MONO_CLASS_PROP_EXCEPTION_DATA for a MonoErrorBoxed with the details */
@@ -336,8 +342,8 @@ struct _MonoClass {
        int        vtable_size; /* number of slots */
 
        guint16     interface_count;
-       guint16     interface_id;        /* unique inderface id (for interfaces) */
-       guint16     max_interface_id;
+       guint32     interface_id;        /* unique inderface id (for interfaces) */
+       guint32     max_interface_id;
        
        guint16     interface_offsets_count;
        MonoClass **interfaces_packed;
@@ -359,14 +365,20 @@ struct _MonoClass {
        /*
         * From the TypeDef table
         */
-       guint32    flags;
        struct {
 #if MONO_SMALL_CONFIG
-               guint16 first, count;
+               guint16 count;
 #else
-               guint32 first, count;
+               guint32 count;
+#endif
+       } field;
+       struct {
+#if MONO_SMALL_CONFIG
+               guint16 count;
+#else
+               guint32 count;
 #endif
-       } field, method;
+       } method;
 
        /* A GC handle pointing to the corresponding type builder/generic param builder */
        guint32 ref_info_handle;
@@ -385,16 +397,10 @@ struct _MonoClass {
        MonoType this_arg;
        MonoType byval_arg;
 
-       MonoGenericClass *generic_class;
-       MonoGenericContainer *generic_container;
-
        MonoGCDescriptor gc_descr;
 
        MonoClassRuntimeInfo *runtime_info;
 
-       /* next element in the class_cache hash list (in MonoImage) */
-       MonoClass *next_class_cache;
-
        /* Generic vtable. Initialized by a call to mono_class_setup_vtable () */
        MonoMethod **vtable;
 
@@ -402,6 +408,40 @@ struct _MonoClass {
        MonoClassExt *ext;
 };
 
+typedef struct {
+       MonoClass class;
+       guint32 flags;
+       /*
+        * From the TypeDef table
+        */
+       guint32 first_method_idx;
+       guint32 first_field_idx;
+       /* next element in the class_cache hash list (in MonoImage) */
+       MonoClass *next_class_cache;
+} MonoClassDef;
+
+typedef struct {
+       MonoClassDef class;
+       MonoGenericContainer *generic_container;
+} MonoClassGtd;
+
+typedef struct {
+       MonoClass class;
+       MonoGenericClass *generic_class;
+} MonoClassGenericInst;
+
+typedef struct {
+       MonoClass class;
+} MonoClassGenericParam;
+
+typedef struct {
+       MonoClass class;
+} MonoClassArray;
+
+typedef struct {
+       MonoClass class;
+} MonoClassPointer;
+
 #ifdef COMPRESSED_INTERFACE_BITMAP
 int mono_compress_bitmap (uint8_t *dest, const uint8_t *bitmap, int size);
 int mono_class_interface_match (const uint8_t *bitmap, int id);
@@ -450,7 +490,7 @@ struct MonoVTable {
        MonoDomain *domain;  /* each object/vtable belongs to exactly one domain */
         gpointer    type; /* System.Type type for klass */
        guint8     *interface_bitmap;
-       guint16     max_interface_id;
+       guint32     max_interface_id;
        guint8      rank;
        guint remote          : 1; /* class is remotely activated */
        guint initialized     : 1; /* cctor has been run */
@@ -1338,9 +1378,6 @@ mono_class_setup_interface_id (MonoClass *klass);
 MonoGenericContainer*
 mono_class_get_generic_container (MonoClass *klass);
 
-MonoGenericClass*
-mono_class_get_generic_class (MonoClass *klass);
-
 gpointer
 mono_class_alloc (MonoClass *klass, int size);
 
@@ -1433,4 +1470,35 @@ mono_error_set_for_class_failure (MonoError *orerror, const MonoClass *klass);
 gboolean
 mono_class_has_failure (const MonoClass *klass);
 
+/* Kind specific accessors */
+MonoGenericClass*
+mono_class_get_generic_class (MonoClass *klass);
+
+MonoGenericClass*
+mono_class_try_get_generic_class (MonoClass *klass);
+
+void
+mono_class_set_flags (MonoClass *klass, guint32 flags);
+
+MonoGenericContainer*
+mono_class_try_get_generic_container (MonoClass *klass);
+
+void
+mono_class_set_generic_container (MonoClass *klass, MonoGenericContainer *container);
+
+guint32
+mono_class_get_first_method_idx (MonoClass *klass);
+
+void
+mono_class_set_first_method_idx (MonoClass *klass, guint32 idx);
+
+guint32
+mono_class_get_first_field_idx (MonoClass *klass);
+
+void
+mono_class_set_first_field_idx (MonoClass *klass, guint32 idx);
+
+/*Now that everything has been defined, let's include the inline functions */
+#include <mono/metadata/class-inlines.h>
+
 #endif /* __MONO_METADATA_CLASS_INTERNALS_H__ */
index fa67e15b0f1404c942742c410d57ef2a714002a7..042c869adccf3ee198a8e02451ca412ce496b3db 100644 (file)
@@ -54,8 +54,9 @@ gboolean mono_print_vtable = FALSE;
 gboolean mono_align_small_structs = FALSE;
 
 /* Statistics */
-guint32 inflated_classes, inflated_classes_size, inflated_methods_size;
-guint32 classes_size, class_ext_size;
+guint32 inflated_classes_size, inflated_methods_size;
+guint32 classes_size, class_ext_size, class_ext_count;
+guint32 class_def_count, class_gtd_count, class_ginst_count, class_gparam_count, class_array_count, class_pointer_count;
 
 /* Low level lock which protects data structures in this module */
 static mono_mutex_t classes_mutex;
@@ -111,6 +112,8 @@ typedef gboolean (*gclass_record_func) (MonoClass*, void*);
 /* This TLS variable points to a GSList of classes which have setup_fields () executing */
 static MonoNativeTlsKey setup_fields_tls_id;
 
+static MonoNativeTlsKey init_pending_tls_id;
+
 static inline void
 classes_lock (void)
 {
@@ -504,8 +507,8 @@ mono_type_get_name_recurse (MonoType *type, GString *str, gboolean is_recursed,
                }
                if (is_recursed)
                        break;
-               if (klass->generic_class) {
-                       MonoGenericClass *gclass = klass->generic_class;
+               if (mono_class_is_ginst (klass)) {
+                       MonoGenericClass *gclass = mono_class_get_generic_class (klass);
                        MonoGenericInst *inst = gclass->context.class_inst;
                        MonoTypeNameFormat nested_format;
                        int i;
@@ -534,7 +537,7 @@ mono_type_get_name_recurse (MonoType *type, GString *str, gboolean is_recursed,
                                g_string_append_c (str, '>');
                        else
                                g_string_append_c (str, ']');
-               } else if (klass->generic_container &&
+               } else if (mono_class_is_gtd (klass) &&
                           (format != MONO_TYPE_NAME_FORMAT_FULL_NAME) &&
                           (format != MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED)) {
                        int i;
@@ -543,10 +546,10 @@ mono_type_get_name_recurse (MonoType *type, GString *str, gboolean is_recursed,
                                g_string_append_c (str, '<');
                        else
                                g_string_append_c (str, '[');
-                       for (i = 0; i < klass->generic_container->type_argc; i++) {
+                       for (i = 0; i < mono_class_get_generic_container (klass)->type_argc; i++) {
                                if (i)
                                        g_string_append_c (str, ',');
-                               g_string_append (str, mono_generic_container_get_param_info (klass->generic_container, i)->name);
+                               g_string_append (str, mono_generic_container_get_param_info (mono_class_get_generic_container (klass), i)->name);
                        }
                        if (format == MONO_TYPE_NAME_FORMAT_IL) 
                                g_string_append_c (str, '>');
@@ -665,7 +668,7 @@ mono_class_is_open_constructed_type (MonoType *t)
                return t->data.generic_class->context.class_inst->is_open;
        case MONO_TYPE_CLASS:
        case MONO_TYPE_VALUETYPE:
-               return t->data.klass->generic_container != NULL;
+               return mono_class_is_gtd (t->data.klass);
        default:
                return FALSE;
        }
@@ -788,7 +791,7 @@ inflate_generic_type (MonoImage *image, MonoType *type, MonoGenericContext *cont
        case MONO_TYPE_CLASS:
        case MONO_TYPE_VALUETYPE: {
                MonoClass *klass = type->data.klass;
-               MonoGenericContainer *container = klass->generic_container;
+               MonoGenericContainer *container = mono_class_try_get_generic_container (klass);
                MonoGenericInst *inst;
                MonoGenericClass *gclass = NULL;
                MonoType *nt;
@@ -825,33 +828,8 @@ mono_generic_class_get_context (MonoGenericClass *gclass)
 MonoGenericContext *
 mono_class_get_context (MonoClass *klass)
 {
-       return klass->generic_class ? mono_generic_class_get_context (klass->generic_class) : NULL;
-}
-
-/*
- * mono_class_get_generic_container:
- *
- *   Return the generic container of KLASS which should be a generic type definition.
- */
-MonoGenericContainer*
-mono_class_get_generic_container (MonoClass *klass)
-{
-       g_assert (klass->is_generic);
-
-       return klass->generic_container;
-}
-
-/*
- * mono_class_get_generic_class:
- *
- *   Return the MonoGenericClass of KLASS, which should be a generic instance.
- */
-MonoGenericClass*
-mono_class_get_generic_class (MonoClass *klass)
-{
-       g_assert (klass->is_inflated);
-
-       return klass->generic_class;
+       MonoGenericClass *gklass = mono_class_try_get_generic_class (klass);
+       return gklass ? mono_generic_class_get_context (gklass) : NULL;
 }
 
 /*
@@ -1082,7 +1060,7 @@ mono_class_inflate_generic_method_full_checked (MonoMethod *method, MonoClass *k
         * 
         */
        if (!((method->is_generic && context->method_inst) || 
-               (method->klass->generic_container && context->class_inst)))
+               (mono_class_is_gtd (method->klass) && context->class_inst)))
                return method;
 
        iresult = g_new0 (MonoMethodInflated, 1);
@@ -1093,14 +1071,12 @@ mono_class_inflate_generic_method_full_checked (MonoMethod *method, MonoClass *k
                iresult->context.method_inst = mono_method_get_generic_container (method)->context.method_inst;
 
        if (!context->class_inst) {
-               g_assert (!iresult->declaring->klass->generic_class);
-               if (iresult->declaring->klass->generic_container)
-                       iresult->context.class_inst = iresult->declaring->klass->generic_container->context.class_inst;
-               else if (iresult->declaring->klass->generic_class)
-                       iresult->context.class_inst = iresult->declaring->klass->generic_class->context.class_inst;
+               g_assert (!mono_class_is_ginst (iresult->declaring->klass));
+               if (mono_class_is_gtd (iresult->declaring->klass))
+                       iresult->context.class_inst = mono_class_get_generic_container (iresult->declaring->klass)->context.class_inst;
        }
        /* This can happen with some callers like mono_object_get_virtual_method () */
-       if (!iresult->declaring->klass->generic_container && !iresult->declaring->klass->generic_class)
+       if (!mono_class_is_gtd (iresult->declaring->klass) && !mono_class_is_ginst (iresult->declaring->klass))
                iresult->context.class_inst = NULL;
 
        MonoImageSet *set = mono_metadata_get_image_set_for_method (iresult);
@@ -1158,12 +1134,13 @@ mono_class_inflate_generic_method_full_checked (MonoMethod *method, MonoClass *k
                }
        }
 
-       if (!klass_hint || !klass_hint->generic_class ||
-           klass_hint->generic_class->container_class != method->klass ||
-           klass_hint->generic_class->context.class_inst != context->class_inst)
-               klass_hint = NULL;
+       if (klass_hint) {
+               MonoGenericClass *gklass_hint = mono_class_try_get_generic_class (klass_hint);
+               if (gklass_hint && (gklass_hint->container_class != method->klass || gklass_hint->context.class_inst != context->class_inst))
+                       klass_hint = NULL;
+       }
 
-       if (method->klass->generic_container)
+       if (mono_class_is_gtd (method->klass))
                result->klass = klass_hint;
 
        if (!result->klass) {
@@ -1238,8 +1215,8 @@ mono_method_get_context_general (MonoMethod *method, gboolean uninflated)
                return NULL;
        if (method->is_generic)
                return &(mono_method_get_generic_container (method)->context);
-       if (method->klass->generic_container)
-               return &method->klass->generic_container->context;
+       if (mono_class_is_gtd (method->klass))
+               return &mono_class_get_generic_container (method->klass)->context;
        return NULL;
 }
 
@@ -1304,31 +1281,31 @@ mono_class_find_enum_basetype (MonoClass *klass, MonoError *error)
        MonoGenericContainer *container = NULL;
        MonoImage *m = klass->image;
        const int top = klass->field.count;
-       int i;
+       int i, first_field_idx;
 
        g_assert (klass->enumtype);
 
        mono_error_init (error);
 
-       if (klass->generic_container)
-               container = klass->generic_container;
-       else if (klass->generic_class) {
-               MonoClass *gklass = klass->generic_class->container_class;
+       container = mono_class_try_get_generic_container (klass);
+       if (mono_class_is_ginst (klass)) {
+               MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
 
-               container = gklass->generic_container;
+               container = mono_class_get_generic_container (gklass);
                g_assert (container);
        }
 
        /*
         * Fetch all the field information.
         */
+       first_field_idx = mono_class_get_first_field_idx (klass);
        for (i = 0; i < top; i++){
                const char *sig;
                guint32 cols [MONO_FIELD_SIZE];
-               int idx = klass->field.first + i;
+               int idx = first_field_idx + i;
                MonoType *ftype;
 
-               /* klass->field.first and idx points into the fieldptr table */
+               /* first_field_idx and idx points into the fieldptr table */
                mono_metadata_decode_table_row (m, MONO_TABLE_FIELD, idx, cols, MONO_FIELD_SIZE);
 
                if (cols [MONO_FIELD_FLAGS] & FIELD_ATTRIBUTE_STATIC) //no need to decode static fields
@@ -1351,7 +1328,7 @@ mono_class_find_enum_basetype (MonoClass *klass, MonoError *error)
                if (!ftype)
                        goto fail;
 
-               if (klass->generic_class) {
+               if (mono_class_is_ginst (klass)) {
                        //FIXME do we leak here?
                        ftype = mono_class_inflate_generic_type_checked (ftype, mono_class_get_context (klass), error);
                        if (!mono_error_ok (error))
@@ -1405,8 +1382,9 @@ mono_error_set_for_class_failure (MonoError *oerror, const MonoClass *klass)
 gpointer
 mono_class_alloc (MonoClass *klass, int size)
 {
-       if (klass->generic_class)
-               return mono_image_set_alloc (klass->generic_class->owner, size);
+       MonoGenericClass *gklass = mono_class_try_get_generic_class (klass);
+       if (gklass)
+               return mono_image_set_alloc (gklass->owner, size);
        else
                return mono_image_alloc (klass->image, size);
 }
@@ -1431,12 +1409,13 @@ mono_class_alloc0 (MonoClass *klass, int size)
  * Initializes the following fields in MonoClass:
  * * klass->fields (only field->parent and field->name)
  * * klass->field.count
- * * klass->field.first
+ * * klass->first_field_idx
  * LOCKING: Acquires the loader lock
  */
 static void
 mono_class_setup_basic_field_info (MonoClass *klass)
 {
+       MonoGenericClass *gklass;
        MonoClassField *field;
        MonoClassField *fields;
        MonoClass *gtd;
@@ -1446,10 +1425,12 @@ mono_class_setup_basic_field_info (MonoClass *klass)
        if (klass->fields)
                return;
 
-       gtd = klass->generic_class ? mono_class_get_generic_type_definition (klass) : NULL;
+       gklass = mono_class_try_get_generic_class (klass);
+       gtd = gklass ? mono_class_get_generic_type_definition (klass) : NULL;
        image = klass->image;
 
-       if (klass->generic_class && image_is_dynamic (klass->generic_class->container_class->image) && !klass->generic_class->container_class->wastypebuilder) {
+
+       if (gklass && image_is_dynamic (gklass->container_class->image) && !gklass->container_class->wastypebuilder) {
                /*
                 * This happens when a generic instance of an unfinished generic typebuilder
                 * is used as an element type for creating an array type. We can't initialize
@@ -1463,7 +1444,6 @@ mono_class_setup_basic_field_info (MonoClass *klass)
                mono_class_setup_basic_field_info (gtd);
 
                mono_loader_lock ();
-               klass->field.first = gtd->field.first;
                klass->field.count = gtd->field.count;
                mono_loader_unlock ();
        }
@@ -1475,15 +1455,16 @@ mono_class_setup_basic_field_info (MonoClass *klass)
        /*
         * Fetch all the field information.
         */
-       for (i = 0; i < top; i++){
+       int first_field_idx = mono_class_has_static_metadata (klass) ? mono_class_get_first_field_idx (klass) : 0;
+       for (i = 0; i < top; i++) {
                field = &fields [i];
                field->parent = klass;
 
                if (gtd) {
                        field->name = mono_field_get_name (&gtd->fields [i]);
                } else {
-                       int idx = klass->field.first + i;
-                       /* klass->field.first and idx points into the fieldptr table */
+                       int idx = first_field_idx + i;
+                       /* first_field_idx and idx points into the fieldptr table */
                        guint32 name_idx = mono_metadata_decode_table_row_col (image, MONO_TABLE_FIELD, idx, MONO_FIELD_NAME);
                        /* The name is needed for fieldrefs */
                        field->name = mono_metadata_string_heap (image, name_idx);
@@ -1532,15 +1513,9 @@ mono_class_set_type_load_failure_causedby_class (MonoClass *klass, const MonoCla
  * Initializes klass->fields, computes class layout and sizes.
  * typebuilder_setup_fields () is the corresponding function for dynamic classes.
  * Sets the following fields in @klass:
- *  - packing_size
- *  - min_align
- *  - blittable
- *  - has_references (if the class contains instance references firled or structs that contain references)
- *  - has_static_refs (same, but for static fields)
- *  - instance_size (size of the object in memory)
- *  - class_size (size needed for the static fields)
- *  - size_inited (flag set when the instance_size is set)
+ *  - all the fields initialized by mono_class_init_sizes ()
  *  - element_class/cast_class (for enums)
+ *  - field->type/offset for all fields
  *  - fields_inited
  *
  * LOCKING: Acquires the loader lock.
@@ -1551,19 +1526,20 @@ mono_class_setup_fields (MonoClass *klass)
        MonoError error;
        MonoImage *m = klass->image;
        int top;
-       guint32 layout = klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK;
+       guint32 layout = mono_class_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK;
        int i;
        guint32 real_size = 0;
        guint32 packing_size = 0;
        int instance_size;
        gboolean explicit_size;
        MonoClassField *field;
-       MonoClass *gtd;
+       MonoGenericClass *gklass = mono_class_try_get_generic_class (klass);
+       MonoClass *gtd = gklass ? mono_class_get_generic_type_definition (klass) : NULL;
 
        if (klass->fields_inited)
                return;
 
-       if (klass->generic_class && image_is_dynamic (klass->generic_class->container_class->image) && !klass->generic_class->container_class->wastypebuilder) {
+       if (gklass && image_is_dynamic (gklass->container_class->image) && !gklass->container_class->wastypebuilder) {
                /*
                 * This happens when a generic instance of an unfinished generic typebuilder
                 * is used as an element type for creating an array type. We can't initialize
@@ -1576,7 +1552,6 @@ mono_class_setup_fields (MonoClass *klass)
        mono_class_setup_basic_field_info (klass);
        top = klass->field.count;
 
-       gtd = klass->generic_class ? mono_class_get_generic_type_definition (klass) : NULL;
        if (gtd) {
                mono_class_setup_fields (gtd);
                if (mono_class_set_type_load_failure_causedby_class (klass, gtd, "Generic type definition failed"))
@@ -1613,8 +1588,9 @@ mono_class_setup_fields (MonoClass *klass)
        /*
         * Fetch all the field information.
         */
+       int first_field_idx = mono_class_has_static_metadata (klass) ? mono_class_get_first_field_idx (klass) : 0;
        for (i = 0; i < top; i++) {
-               int idx = klass->field.first + i;
+               int idx = first_field_idx + i;
                field = &klass->fields [i];
 
                if (!field->type) {
@@ -1644,7 +1620,7 @@ mono_class_setup_fields (MonoClass *klass)
                                mono_class_set_type_load_failure (klass, "Field '%s' has a negative offset %d", field->name, offset);
                                break;
                        }
-                       if (klass->generic_container) {
+                       if (mono_class_is_gtd (klass)) {
                                mono_class_set_type_load_failure (klass, "Generic class cannot have explicit layout.");
                                break;
                        }
@@ -1669,23 +1645,51 @@ mono_class_setup_fields (MonoClass *klass)
        mono_native_tls_set_value (setup_fields_tls_id, init_list);
 }
 
+static void
+init_sizes_with_info (MonoClass *klass, MonoCachedClassInfo *cached_info)
+{
+       if (cached_info) {
+               klass->instance_size = cached_info->instance_size;
+               klass->sizes.class_size = cached_info->class_size;
+               klass->packing_size = cached_info->packing_size;
+               klass->min_align = cached_info->min_align;
+               klass->blittable = cached_info->blittable;
+               klass->has_references = cached_info->has_references;
+               klass->has_static_refs = cached_info->has_static_refs;
+               klass->no_special_static_fields = cached_info->no_special_static_fields;
+       }
+       else {
+               if (!klass->size_inited)
+                       mono_class_setup_fields (klass);
+       }
+}
 /*
- * mono_class_has_references:
+
+ * mono_class_init_sizes:
+ *
+ *   Initializes the size related fields of @klass without loading all field data if possible.
+ * Sets the following fields in @klass:
+ * - instance_size
+ * - sizes.class_size
+ * - packing_size
+ * - min_align
+ * - blittable
+ * - has_references
+ * - has_static_refs
+ * - size_inited
+ * Can fail the class.
  *
- *   Returns whenever @klass->has_references is set, initializing it if needed.
- * Aquires the loader lock.
+ * LOCKING: Acquires the loader lock.
  */
-static gboolean
-mono_class_has_references (MonoClass *klass)
+static void
+mono_class_init_sizes (MonoClass *klass)
 {
-       if (klass->init_pending) {
-               /* Be conservative */
-               return TRUE;
-       } else {
-               mono_class_init (klass);
+       MonoCachedClassInfo cached_info;
+       gboolean has_cached_info;
 
-               return klass->has_references;
-       }
+       has_cached_info = mono_class_get_cached_class_info (klass, &cached_info);
+
+       init_sizes_with_info (klass, has_cached_info ? &cached_info : NULL);
 }
 
 /*
@@ -1705,16 +1709,29 @@ mono_type_get_basic_type_from_generic (MonoType *type)
        return type;
 }
 
+static gboolean
+class_has_references (MonoClass *klass)
+{
+       mono_class_init_sizes (klass);
+
+       /*
+        * has_references is not set if this is called recursively, but this is not a problem since this is only used
+        * during field layout, and instance fields are initialized before static fields, and instance fields can't
+        * embed themselves.
+        */
+       return klass->has_references;
+}
+
 static gboolean
 type_has_references (MonoClass *klass, MonoType *ftype)
 {
-       if (MONO_TYPE_IS_REFERENCE (ftype) || IS_GC_REFERENCE (klass, ftype) || ((MONO_TYPE_ISSTRUCT (ftype) && mono_class_has_references (mono_class_from_mono_type (ftype)))))
+       if (MONO_TYPE_IS_REFERENCE (ftype) || IS_GC_REFERENCE (klass, ftype) || ((MONO_TYPE_ISSTRUCT (ftype) && class_has_references (mono_class_from_mono_type (ftype)))))
                return TRUE;
        if (!ftype->byref && (ftype->type == MONO_TYPE_VAR || ftype->type == MONO_TYPE_MVAR)) {
                MonoGenericParam *gparam = ftype->data.generic_param;
 
                if (gparam->gshared_constraint)
-                       return mono_class_has_references (mono_class_from_mono_type (gparam->gshared_constraint));
+                       return class_has_references (mono_class_from_mono_type (gparam->gshared_constraint));
        }
        return FALSE;
 }
@@ -1736,7 +1753,7 @@ mono_class_layout_fields (MonoClass *klass, int base_instance_size, int packing_
 {
        int i;
        const int top = klass->field.count;
-       guint32 layout = klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK;
+       guint32 layout = mono_class_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK;
        guint32 pass, passes, real_size;
        gboolean gc_aware_layout = FALSE;
        gboolean has_static_fields = FALSE;
@@ -1876,6 +1893,7 @@ mono_class_layout_fields (MonoClass *klass, int base_instance_size, int packing_
         * Compute field layout and total size (not considering static fields)
         */
        field_offsets = g_new0 (int, top);
+       int first_field_idx = mono_class_has_static_metadata (klass) ? mono_class_get_first_field_idx (klass) : 0;
        switch (layout) {
        case TYPE_ATTRIBUTE_AUTO_LAYOUT:
        case TYPE_ATTRIBUTE_SEQUENTIAL_LAYOUT:
@@ -1984,7 +2002,7 @@ mono_class_layout_fields (MonoClass *klass, int base_instance_size, int packing_
                                /* Already set by typebuilder_setup_fields () */
                                field_offsets [i] = field->offset + sizeof (MonoObject);
                        } else {
-                               int idx = klass->field.first + i;
+                               int idx = first_field_idx + i;
                                guint32 offset;
                                mono_metadata_field_info (klass->image, idx, &offset, NULL, NULL);
                                field_offsets [i] = offset + sizeof (MonoObject);
@@ -2205,9 +2223,9 @@ mono_class_setup_methods (MonoClass *klass)
        if (klass->methods)
                return;
 
-       if (klass->generic_class) {
+       if (mono_class_is_ginst (klass)) {
                MonoError error;
-               MonoClass *gklass = klass->generic_class->container_class;
+               MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
 
                mono_class_init (gklass);
                if (!mono_class_has_failure (gklass))
@@ -2321,19 +2339,23 @@ mono_class_setup_methods (MonoClass *klass)
 
                for (i = 0; i < klass->interface_count; i++)
                        setup_generic_array_ifaces (klass, klass->interfaces [i], methods, first_generic + i * count_generic);
-       } else {
+       } else if (mono_class_has_static_metadata (klass)) {
                MonoError error;
+               int first_idx = mono_class_get_first_method_idx (klass);
 
                count = klass->method.count;
                methods = (MonoMethod **)mono_class_alloc (klass, sizeof (MonoMethod*) * count);
                for (i = 0; i < count; ++i) {
-                       int idx = mono_metadata_translate_token_index (klass->image, MONO_TABLE_METHOD, klass->method.first + i + 1);
+                       int idx = mono_metadata_translate_token_index (klass->image, MONO_TABLE_METHOD, first_idx + i + 1);
                        methods [i] = mono_get_method_checked (klass->image, MONO_TOKEN_METHOD_DEF | idx, klass, NULL, &error);
                        if (!methods [i]) {
                                mono_class_set_type_load_failure (klass, "Could not load method %d due to %s", i, mono_error_get_message (&error));
                                mono_error_cleanup (&error);
                        }
                }
+       } else {
+               methods = (MonoMethod **)mono_class_alloc (klass, sizeof (MonoMethod*) * 1);
+               count = 0;
        }
 
        if (MONO_CLASS_IS_INTERFACE (klass)) {
@@ -2370,13 +2392,14 @@ MonoMethod*
 mono_class_get_method_by_index (MonoClass *klass, int index)
 {
        MonoError error;
+
+       MonoGenericClass *gklass = mono_class_try_get_generic_class (klass);
        /* Avoid calling setup_methods () if possible */
-       if (klass->generic_class && !klass->methods) {
-               MonoClass *gklass = klass->generic_class->container_class;
+       if (gklass && !klass->methods) {
                MonoMethod *m;
 
                m = mono_class_inflate_generic_method_full_checked (
-                               gklass->methods [index], klass, mono_class_get_context (klass), &error);
+                               gklass->container_class->methods [index], klass, mono_class_get_context (klass), &error);
                g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
                /*
                 * If setup_methods () is called later for this class, no duplicates are created,
@@ -2406,7 +2429,7 @@ mono_class_get_method_by_index (MonoClass *klass, int index)
 MonoMethod*
 mono_class_get_inflated_method (MonoClass *klass, MonoMethod *method)
 {
-       MonoClass *gklass = klass->generic_class->container_class;
+       MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
        int i;
 
        g_assert (method->klass == gklass);
@@ -2451,9 +2474,9 @@ mono_class_get_vtable_entry (MonoClass *klass, int offset)
                        return klass->parent->vtable [offset];
        }
 
-       if (klass->generic_class) {
+       if (mono_class_is_ginst (klass)) {
                MonoError error;
-               MonoClass *gklass = klass->generic_class->container_class;
+               MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
                mono_class_setup_vtable (gklass);
                m = gklass->vtable [offset];
 
@@ -2502,8 +2525,8 @@ mono_class_setup_properties (MonoClass *klass)
        if (klass->ext && klass->ext->properties)
                return;
 
-       if (klass->generic_class) {
-               MonoClass *gklass = klass->generic_class->container_class;
+       if (mono_class_is_ginst (klass)) {
+               MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
 
                mono_class_init (gklass);
                mono_class_setup_properties (gklass);
@@ -2549,6 +2572,7 @@ mono_class_setup_properties (MonoClass *klass)
                        properties [i - first].name = mono_metadata_string_heap (klass->image, cols [MONO_PROPERTY_NAME]);
 
                        startm = mono_metadata_methods_from_property (klass->image, i, &endm);
+                       int first_idx = mono_class_get_first_method_idx (klass);
                        for (j = startm; j < endm; ++j) {
                                MonoMethod *method;
 
@@ -2560,7 +2584,7 @@ mono_class_setup_properties (MonoClass *klass)
                                        method = mono_get_method_checked (klass->image, MONO_TOKEN_METHOD_DEF | cols [MONO_METHOD_SEMA_METHOD], klass, NULL, &error);
                                        mono_error_cleanup (&error); /* FIXME don't swallow this error */
                                } else {
-                                       method = klass->methods [cols [MONO_METHOD_SEMA_METHOD] - 1 - klass->method.first];
+                                       method = klass->methods [cols [MONO_METHOD_SEMA_METHOD] - 1 - first_idx];
                                }
 
                                switch (cols [MONO_METHOD_SEMA_SEMANTICS]) {
@@ -2633,8 +2657,8 @@ mono_class_setup_events (MonoClass *klass)
        if (klass->ext && klass->ext->events)
                return;
 
-       if (klass->generic_class) {
-               MonoClass *gklass = klass->generic_class->container_class;
+       if (mono_class_is_ginst (klass)) {
+               MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
                MonoGenericContext *context = NULL;
 
                mono_class_setup_events (gklass);
@@ -2691,6 +2715,7 @@ mono_class_setup_events (MonoClass *klass)
                        event->name = mono_metadata_string_heap (klass->image, cols [MONO_EVENT_NAME]);
 
                        startm = mono_metadata_methods_from_event (klass->image, i, &endm);
+                       int first_idx = mono_class_get_first_method_idx (klass);
                        for (j = startm; j < endm; ++j) {
                                MonoMethod *method;
 
@@ -2702,7 +2727,7 @@ mono_class_setup_events (MonoClass *klass)
                                        method = mono_get_method_checked (klass->image, MONO_TOKEN_METHOD_DEF | cols [MONO_METHOD_SEMA_METHOD], klass, NULL, &error);
                                        mono_error_cleanup (&error); /* FIXME don't swallow this error */
                                } else {
-                                       method = klass->methods [cols [MONO_METHOD_SEMA_METHOD] - 1 - klass->method.first];
+                                       method = klass->methods [cols [MONO_METHOD_SEMA_METHOD] - 1 - first_idx];
                                }
 
                                switch (cols [MONO_METHOD_SEMA_SEMANTICS]) {
@@ -2801,7 +2826,7 @@ mono_unload_interface_id (MonoClass *klass)
  * LOCKING: Acquires the classes lock.
  * Returns: The new ID.
  */
-static guint
+static guint32
 mono_get_unique_iid (MonoClass *klass)
 {
        int iid;
@@ -2824,7 +2849,7 @@ mono_get_unique_iid (MonoClass *klass)
        }
        mono_bitset_set (global_interface_bitset, iid);
        /* set the bit also in the per-image set */
-       if (!klass->generic_class) {
+       if (!mono_class_is_ginst (klass)) {
                if (klass->image->interface_bitset) {
                        if (iid >= mono_bitset_size (klass->image->interface_bitset)) {
                                MonoBitSet *new_set = mono_bitset_clone (klass->image->interface_bitset, iid + 1);
@@ -2843,8 +2868,9 @@ mono_get_unique_iid (MonoClass *klass)
        if (mono_print_vtable) {
                int generic_id;
                char *type_name = mono_type_full_name (&klass->byval_arg);
-               if (klass->generic_class && !klass->generic_class->context.class_inst->is_open) {
-                       generic_id = klass->generic_class->context.class_inst->id;
+               MonoGenericClass *gklass = mono_class_try_get_generic_class (klass);
+               if (gklass && !gklass->context.class_inst->is_open) {
+                       generic_id = gklass->context.class_inst->id;
                        g_assert (generic_id != 0);
                } else {
                        generic_id = 0;
@@ -2854,7 +2880,9 @@ mono_get_unique_iid (MonoClass *klass)
        }
 #endif
 
-       g_assert (iid <= 65535);
+       /* I've confirmed iids safe past 16 bits, however bitset code uses a signed int while testing.
+        * Once this changes, it should be safe for us to allow 2^32-1 interfaces, until then 2^31-2 is the max. */
+       g_assert (iid < INT_MAX);
        return iid;
 }
 
@@ -3057,6 +3085,12 @@ fill_valuetype_array_derived_types (MonoClass **valuetype_types, MonoClass *ecla
                valuetype_types [1] = mono_class_from_mono_type (mono_class_enum_basetype (eclass));
 }
 
+static GENERATE_GET_CLASS_WITH_CACHE (generic_icollection, System.Collections.Generic, ICollection`1)
+static GENERATE_GET_CLASS_WITH_CACHE (generic_ienumerable, System.Collections.Generic, IEnumerable`1)
+static GENERATE_GET_CLASS_WITH_CACHE (generic_ienumerator, System.Collections.Generic, IEnumerator`1)
+static GENERATE_GET_CLASS_WITH_CACHE (generic_ireadonlylist, System.Collections.Generic, IReadOnlyList`1)
+static GENERATE_GET_CLASS_WITH_CACHE (generic_ireadonlycollection, System.Collections.Generic, IReadOnlyCollection`1)
+
 /* this won't be needed once bug #325495 is completely fixed
  * though we'll need something similar to know which interfaces to allow
  * in arrays when they'll be lazyly created
@@ -3074,11 +3108,11 @@ static MonoClass**
 get_implicit_generic_array_interfaces (MonoClass *klass, int *num, int *is_enumerator)
 {
        MonoClass *eclass = klass->element_class;
-       static MonoClass* generic_icollection_class = NULL;
-       static MonoClass* generic_ienumerable_class = NULL;
-       static MonoClass* generic_ienumerator_class = NULL;
-       static MonoClass* generic_ireadonlylist_class = NULL;
-       static MonoClass* generic_ireadonlycollection_class = NULL;
+       MonoClass* generic_icollection_class;
+       MonoClass* generic_ienumerable_class;
+       MonoClass* generic_ienumerator_class;
+       MonoClass* generic_ireadonlylist_class;
+       MonoClass* generic_ireadonlycollection_class;
        MonoClass *valuetype_types[2] = { NULL, NULL };
        MonoClass **interfaces = NULL;
        int i, nifaces, interface_count, real_count, original_rank;
@@ -3094,11 +3128,12 @@ get_implicit_generic_array_interfaces (MonoClass *klass, int *num, int *is_enume
        eclass_is_valuetype = FALSE;
        original_rank = eclass->rank;
        if (klass->byval_arg.type != MONO_TYPE_SZARRAY) {
-               if (klass->generic_class && klass->nested_in == mono_defaults.array_class && strcmp (klass->name, "InternalEnumerator`1") == 0)  {
+               MonoGenericClass *gklass = mono_class_try_get_generic_class (klass);
+               if (gklass && klass->nested_in == mono_defaults.array_class && strcmp (klass->name, "InternalEnumerator`1") == 0)        {
                        /*
                         * For a Enumerator<T[]> we need to get the list of interfaces for T.
                         */
-                       eclass = mono_class_from_mono_type (klass->generic_class->context.class_inst->type_argv [0]);
+                       eclass = mono_class_from_mono_type (gklass->context.class_inst->type_argv [0]);
                        original_rank = eclass->rank;
                        if (!eclass->rank)
                                eclass = eclass->element_class;
@@ -3116,18 +3151,11 @@ get_implicit_generic_array_interfaces (MonoClass *klass, int *num, int *is_enume
         */
        all_interfaces = eclass->rank && eclass->element_class->rank? FALSE: TRUE;
 
-       if (!generic_icollection_class) {
-               generic_icollection_class = mono_class_load_from_name (mono_defaults.corlib,
-                       "System.Collections.Generic", "ICollection`1");
-               generic_ienumerable_class = mono_class_load_from_name (mono_defaults.corlib,
-                       "System.Collections.Generic", "IEnumerable`1");
-               generic_ienumerator_class = mono_class_load_from_name (mono_defaults.corlib,
-                       "System.Collections.Generic", "IEnumerator`1");
-               generic_ireadonlylist_class = mono_class_load_from_name (mono_defaults.corlib,
-                       "System.Collections.Generic", "IReadOnlyList`1");
-               generic_ireadonlycollection_class = mono_class_load_from_name (mono_defaults.corlib,
-                       "System.Collections.Generic", "IReadOnlyCollection`1");
-       }
+       generic_icollection_class = mono_class_get_generic_icollection_class ();
+       generic_ienumerable_class = mono_class_get_generic_ienumerable_class ();
+       generic_ienumerator_class = mono_class_get_generic_ienumerator_class ();
+       generic_ireadonlylist_class = mono_class_get_generic_ireadonlylist_class ();
+       generic_ireadonlycollection_class = mono_class_get_generic_ireadonlycollection_class ();
 
        mono_class_init (eclass);
 
@@ -3318,8 +3346,9 @@ count_virtual_methods (MonoClass *klass)
                                ++count;
                }
        } else {
+               int first_idx = mono_class_get_first_method_idx (klass);
                for (i = 0; i < klass->method.count; ++i) {
-                       flags = mono_metadata_decode_table_row_col (klass->image, MONO_TABLE_METHOD, klass->method.first + i, MONO_METHOD_FLAGS);
+                       flags = mono_metadata_decode_table_row_col (klass->image, MONO_TABLE_METHOD, first_idx + i, MONO_METHOD_FLAGS);
 
                        if (flags & METHOD_ATTRIBUTE_VIRTUAL)
                                ++count;
@@ -3493,15 +3522,16 @@ mono_class_interface_match (const uint8_t *bitmap, int id)
 #endif
 
 /*
- * LOCKING: this is supposed to be called with the loader lock held.
  * Return -1 on failure and set klass->has_failure and store a MonoErrorBoxed with the details.
+ * LOCKING: Acquires the loader lock.
  */
 static int
 setup_interface_offsets (MonoClass *klass, int cur_slot, gboolean overwrite)
 {
        MonoError error;
        MonoClass *k, *ic;
-       int i, j, max_iid, num_ifaces;
+       int i, j, num_ifaces;
+       guint32 max_iid;
        MonoClass **interfaces_full = NULL;
        int *interface_offsets_full = NULL;
        GPtrArray *ifaces;
@@ -3529,8 +3559,7 @@ setup_interface_offsets (MonoClass *klass, int cur_slot, gboolean overwrite)
                for (i = 0; i < k->interface_count; i++) {
                        ic = k->interfaces [i];
 
-                       if (!ic->inited)
-                               mono_class_init (ic);
+                       mono_class_init (ic);
 
                        if (max_iid < ic->interface_id)
                                max_iid = ic->interface_id;
@@ -3567,14 +3596,13 @@ setup_interface_offsets (MonoClass *klass, int cur_slot, gboolean overwrite)
                if (max_iid < klass->interface_id)
                        max_iid = klass->interface_id;
        }
-       klass->max_interface_id = max_iid;
+
        /* compute vtable offset for interfaces */
        interfaces_full = (MonoClass **)g_malloc0 (sizeof (MonoClass*) * num_ifaces);
        interface_offsets_full = (int *)g_malloc (sizeof (int) * num_ifaces);
 
-       for (i = 0; i < num_ifaces; i++) {
+       for (i = 0; i < num_ifaces; i++)
                interface_offsets_full [i] = -1;
-       }
 
        /* skip the current class */
        for (j = 0; j < klass->idepth - 1; j++) {
@@ -3648,7 +3676,7 @@ setup_interface_offsets (MonoClass *klass, int cur_slot, gboolean overwrite)
                        for (i = 0; i < num_array_interfaces; ++i) {
                                int offset;
                                ic = array_interfaces [i];
-                               if (ic->generic_class->container_class == mono_defaults.generic_ilist_class)
+                               if (mono_class_get_generic_class (ic)->container_class == mono_defaults.generic_ilist_class)
                                        offset = ilist_offset;
                                else if (strcmp (ic->name, "ICollection`1") == 0)
                                        offset = icollection_offset;
@@ -3667,11 +3695,14 @@ setup_interface_offsets (MonoClass *klass, int cur_slot, gboolean overwrite)
        }
 
        for (interface_offsets_count = 0, i = 0; i < num_ifaces; i++) {
-               if (interface_offsets_full [i] != -1) {
+               if (interface_offsets_full [i] != -1)
                        interface_offsets_count ++;
-               }
        }
 
+       /* Publish the data */
+       mono_loader_lock ();
+
+       klass->max_interface_id = max_iid;
        /*
         * We might get called multiple times:
         * - mono_class_init ()
@@ -3696,7 +3727,7 @@ setup_interface_offsets (MonoClass *klass, int cur_slot, gboolean overwrite)
                bitmap = (uint8_t *)mono_class_alloc0 (klass, bsize);
 #endif
                for (i = 0; i < interface_offsets_count; i++) {
-                       int id = interfaces_full [i]->interface_id;
+                       guint32 id = interfaces_full [i]->interface_id;
                        bitmap [id >> 3] |= (1 << (id & 7));
                        klass->interfaces_packed [i] = interfaces_full [i];
                        klass->interface_offsets_packed [i] = interface_offsets_full [i];
@@ -3712,6 +3743,7 @@ setup_interface_offsets (MonoClass *klass, int cur_slot, gboolean overwrite)
                klass->interface_bitmap = bitmap;
 #endif
        }
+       mono_loader_unlock ();
 
 end:
        g_free (interfaces_full);
@@ -3726,7 +3758,7 @@ end:
        
        //printf ("JUST DONE: ");
        //print_implemented_interfaces (klass);
+
        return cur_slot;
 }
 
@@ -3744,11 +3776,7 @@ end:
 void
 mono_class_setup_interface_offsets (MonoClass *klass)
 {
-       mono_loader_lock ();
-
        setup_interface_offsets (klass, 0, FALSE);
-
-       mono_loader_unlock ();
 }
 
 /*Checks if @klass has @parent as one of it's parents type gtd
@@ -3775,16 +3803,17 @@ mono_class_check_vtable_constraints (MonoClass *klass, GList *in_setup)
 {
        MonoGenericInst *ginst;
        int i;
-       if (!klass->generic_class) {
+
+       if (!mono_class_is_ginst (klass)) {
                mono_class_setup_vtable_full (klass, in_setup);
                return !mono_class_has_failure (klass);
        }
 
        mono_class_setup_vtable_full (mono_class_get_generic_type_definition (klass), in_setup);
-       if (mono_class_set_type_load_failure_causedby_class (klass, klass->generic_class->container_class, "Failed to load generic definition vtable"))
+       if (mono_class_set_type_load_failure_causedby_class (klass, mono_class_get_generic_class (klass)->container_class, "Failed to load generic definition vtable"))
                return FALSE;
 
-       ginst = klass->generic_class->context.class_inst;
+       ginst = mono_class_get_generic_class (klass)->context.class_inst;
        for (i = 0; i < ginst->type_argc; ++i) {
                MonoClass *arg;
                if (ginst->type_argv [i]->type != MONO_TYPE_GENERICINST)
@@ -3855,7 +3884,7 @@ mono_class_setup_vtable_full (MonoClass *klass, GList *in_setup)
        mono_stats.generic_vtable_count ++;
        in_setup = g_list_prepend (in_setup, klass);
 
-       if (klass->generic_class) {
+       if (mono_class_is_ginst (klass)) {
                if (!mono_class_check_vtable_constraints (klass, in_setup)) {
                        mono_loader_unlock ();
                        g_list_remove (in_setup, klass);
@@ -3863,9 +3892,9 @@ mono_class_setup_vtable_full (MonoClass *klass, GList *in_setup)
                }
 
                context = mono_class_get_context (klass);
-               type_token = klass->generic_class->container_class->type_token;
+               type_token = mono_class_get_generic_class (klass)->container_class->type_token;
        } else {
-               context = (MonoGenericContext *) klass->generic_container;
+               context = (MonoGenericContext *) mono_class_try_get_generic_container (klass); //FIXME is this a case of a try?
                type_token = klass->type_token;
        }
 
@@ -4328,7 +4357,8 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o
        MonoError error;
        MonoClass *k, *ic;
        MonoMethod **vtable;
-       int i, max_vtsize = 0, max_iid, cur_slot = 0;
+       int i, max_vtsize = 0, cur_slot = 0;
+       guint32 max_iid;
        GPtrArray *ifaces = NULL;
        GHashTable *override_map = NULL;
        MonoMethod *cm;
@@ -4393,9 +4423,9 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o
        DEBUG_INTERFACE_VTABLE (first_non_interface_slot = cur_slot);
 
        /* Optimized version for generic instances */
-       if (klass->generic_class) {
+       if (mono_class_is_ginst (klass)) {
                MonoError error;
-               MonoClass *gklass = klass->generic_class->container_class;
+               MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
                MonoMethod **tmp;
 
                mono_class_setup_vtable_full (gklass, in_setup);
@@ -4612,7 +4642,7 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o
        // it can happen (for injected generic array interfaces) that the same slot is
        // processed multiple times (those interfaces have overlapping slots), and it
        // will not always be the first pass the one that fills the slot.
-       if (! (klass->flags & TYPE_ATTRIBUTE_ABSTRACT)) {
+       if (!mono_class_is_abstract (klass)) {
                for (i = 0; i < klass->interface_offsets_count; i++) {
                        int ic_offset;
                        int im_index;
@@ -4756,7 +4786,7 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o
        virt_methods = NULL;
 
        /* Ensure that all vtable slots are filled with concrete instance methods */
-       if (!(klass->flags & TYPE_ATTRIBUTE_ABSTRACT)) {
+       if (!mono_class_is_abstract (klass)) {
                for (i = 0; i < cur_slot; ++i) {
                        if (vtable [i] == NULL || (vtable [i]->flags & (METHOD_ATTRIBUTE_ABSTRACT | METHOD_ATTRIBUTE_STATIC))) {
                                char *type_name = mono_type_get_full_name (klass);
@@ -4769,8 +4799,8 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o
                }
        }
 
-       if (klass->generic_class) {
-               MonoClass *gklass = klass->generic_class->container_class;
+       if (mono_class_is_ginst (klass)) {
+               MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
 
                mono_class_init (gklass);
 
@@ -4873,14 +4903,14 @@ mono_method_get_vtable_slot (MonoMethod *method)
                        MonoClass *gklass;
                        int i;
 
-                       if (!method->klass->generic_class) {
+                       if (!mono_class_is_ginst (method->klass)) {
                                g_assert (method->is_inflated);
                                return mono_method_get_vtable_slot (((MonoMethodInflated*)method)->declaring);
                        }
 
                        /* This can happen for abstract methods of generic instances due to the shortcut code in mono_class_setup_vtable_general (). */
-                       g_assert (method->klass->generic_class);
-                       gklass = method->klass->generic_class->container_class;
+                       g_assert (mono_class_is_ginst (method->klass));
+                       gklass = mono_class_get_generic_class (method->klass)->container_class;
                        mono_class_setup_methods (method->klass);
                        g_assert (method->klass->methods);
                        for (i = 0; i < method->klass->method.count; ++i) {
@@ -5021,7 +5051,7 @@ setup_generic_array_ifaces (MonoClass *klass, MonoClass *iface, MonoMethod **met
        int i;
 
        tmp_context.class_inst = NULL;
-       tmp_context.method_inst = iface->generic_class->context.class_inst;
+       tmp_context.method_inst = mono_class_get_generic_class (iface)->context.class_inst;
        //g_print ("setting up array interface: %s\n", mono_type_get_name_full (&iface->byval_arg, 0));
 
        for (i = 0; i < generic_array_method_num; i++) {
@@ -5051,21 +5081,30 @@ concat_two_strings_with_zero (MonoImage *image, const char *s1, const char *s2)
 
 /**
  * mono_class_init:
- * @class: the class to initialize
+ * @klass: the class to initialize
  *
  *   Compute the instance_size, class_size and other infos that cannot be 
  * computed at mono_class_get() time. Also compute vtable_size if possible. 
  * Returns TRUE on success or FALSE if there was a problem in loading
- * the type (incorrect assemblies, missing assemblies, methods, etc). 
+ * the type (incorrect assemblies, missing assemblies, methods, etc).
+ * Initializes the following fields in @klass:
+ * - all the fields initialized by mono_class_init_sizes ()
+ * - has_cctor
+ * - ghcimpl
+ * - inited
  *
  * LOCKING: Acquires the loader lock.
  */
 gboolean
 mono_class_init (MonoClass *klass)
 {
-       int i;
+       int i, vtable_size = 0, array_method_count = 0;
        MonoCachedClassInfo cached_info;
        gboolean has_cached_info;
+       gboolean locked = FALSE;
+       gboolean ghcimpl = FALSE;
+       gboolean has_cctor = FALSE;
+       int first_iface_slot = 0;
        
        g_assert (klass);
 
@@ -5075,28 +5114,27 @@ mono_class_init (MonoClass *klass)
 
        /*g_print ("Init class %s\n", mono_type_get_full_name (klass));*/
 
-       /* We do everything inside the lock to prevent races */
-       mono_loader_lock ();
-
-       if (klass->inited || mono_class_has_failure (klass)) {
-               mono_loader_unlock ();
-               /* Somebody might have gotten in before us */
-               return !mono_class_has_failure (klass);
-       }
-
-       if (klass->init_pending) {
+       /*
+        * This function can recursively call itself.
+        */
+       GSList *init_list = (GSList *)mono_native_tls_get_value (init_pending_tls_id);
+       if (g_slist_find (init_list, klass)) {
                mono_class_set_type_load_failure (klass, "Recursive type definition detected");
                goto leave;
        }
+       init_list = g_slist_prepend (init_list, klass);
+       mono_native_tls_set_value (init_pending_tls_id, init_list);
 
-       klass->init_pending = 1;
+       /*
+        * We want to avoid doing complicated work inside locks, so we compute all the required
+        * information and write it to @klass inside a lock.
+        */
 
        if (mono_verifier_is_enabled_for_class (klass) && !mono_verifier_verify_class (klass)) {
                mono_class_set_type_load_failure (klass, "%s", concat_two_strings_with_zero (klass->image, klass->name, klass->image->assembly_name));
                goto leave;
        }
 
-
        if (klass->byval_arg.type == MONO_TYPE_ARRAY || klass->byval_arg.type == MONO_TYPE_SZARRAY) {
                MonoClass *element_class = klass->element_class;
                if (!element_class->inited) 
@@ -5107,23 +5145,14 @@ mono_class_init (MonoClass *klass)
 
        mono_stats.initialized_class_count++;
 
-       if (klass->generic_class && !klass->generic_class->is_dynamic) {
-               MonoClass *gklass = klass->generic_class->container_class;
-
-               mono_stats.generic_class_count++;
-
-               klass->method = gklass->method;
-               klass->field = gklass->field;
+       if (mono_class_is_ginst (klass) && !mono_class_get_generic_class (klass)->is_dynamic) {
+               MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
 
                mono_class_init (gklass);
-               // FIXME: Why is this needed ?
-               if (!mono_class_has_failure (gklass))
-                       mono_class_setup_methods (gklass);
                if (mono_class_set_type_load_failure_causedby_class (klass, gklass, "Generic Type Definition failed to init"))
                        goto leave;
 
-               if (MONO_CLASS_IS_INTERFACE (klass))
-                       klass->interface_id = mono_get_unique_iid (klass);
+               mono_class_setup_interface_id (klass);
        }
 
        if (klass->parent && !klass->parent->inited)
@@ -5131,38 +5160,10 @@ mono_class_init (MonoClass *klass)
 
        has_cached_info = mono_class_get_cached_class_info (klass, &cached_info);
 
-       if (klass->generic_class || image_is_dynamic (klass->image) || !klass->type_token || (has_cached_info && !cached_info.has_nested_classes))
-               klass->nested_classes_inited = TRUE;
-
-       /*
-        * Computes the size used by the fields, and their locations
-        */
-       if (has_cached_info) {
-               klass->instance_size = cached_info.instance_size;
-               klass->sizes.class_size = cached_info.class_size;
-               klass->packing_size = cached_info.packing_size;
-               klass->min_align = cached_info.min_align;
-               klass->blittable = cached_info.blittable;
-               klass->has_references = cached_info.has_references;
-               klass->has_static_refs = cached_info.has_static_refs;
-               klass->no_special_static_fields = cached_info.no_special_static_fields;
-       }
-       else
-               if (!klass->size_inited){
-                       mono_class_setup_fields (klass);
-                       if (mono_class_has_failure (klass))
-                               goto leave;
-               }
-                               
-       /* Initialize arrays */
-       if (klass->rank) {
-               klass->method.count = 3 + (klass->rank > 1? 2: 1);
-
-               if (klass->interface_count) {
-                       int count_generic = generic_array_methods (klass);
-                       klass->method.count += klass->interface_count * count_generic;
-               }
-       }
+       /* Compute instance size etc. */
+       init_sizes_with_info (klass, has_cached_info ? &cached_info : NULL);
+       if (mono_class_has_failure (klass))
+               goto leave;
 
        mono_class_setup_supertypes (klass);
 
@@ -5176,11 +5177,9 @@ mono_class_init (MonoClass *klass)
         */
        if (has_cached_info) {
                /* AOT case */
-               klass->vtable_size = cached_info.vtable_size;
-               klass->has_finalize = cached_info.has_finalize;
-               klass->has_finalize_inited = TRUE;
-               klass->ghcimpl = cached_info.ghcimpl;
-               klass->has_cctor = cached_info.has_cctor;
+               vtable_size = cached_info.vtable_size;
+               ghcimpl = cached_info.ghcimpl;
+               has_cctor = cached_info.has_cctor;
        } else if (klass->rank == 1 && klass->byval_arg.type == MONO_TYPE_SZARRAY) {
                /* SZARRAY can have 2 vtable layouts, with and without the stelemref method.
                 * The first slot if for array with.
@@ -5193,21 +5192,22 @@ mono_class_init (MonoClass *klass)
                if (!szarray_vtable_size [slot]) {
                        mono_class_setup_vtable (klass);
                        szarray_vtable_size [slot] = klass->vtable_size;
+                       vtable_size = klass->vtable_size;
                } else {
-                       klass->vtable_size = szarray_vtable_size[slot];
+                       vtable_size = szarray_vtable_size[slot];
                }
-       } else if (klass->generic_class && !MONO_CLASS_IS_INTERFACE (klass)) {
-               MonoClass *gklass = klass->generic_class->container_class;
+       } else if (mono_class_is_ginst (klass) && !MONO_CLASS_IS_INTERFACE (klass)) {
+               MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
 
                /* Generic instance case */
-               klass->ghcimpl = gklass->ghcimpl;
-               klass->has_cctor = gklass->has_cctor;
+               ghcimpl = gklass->ghcimpl;
+               has_cctor = gklass->has_cctor;
 
                mono_class_setup_vtable (gklass);
                if (mono_class_set_type_load_failure_causedby_class (klass, gklass, "Generic type definition failed to init"))
                        goto leave;
 
-               klass->vtable_size = gklass->vtable_size;
+               vtable_size = gklass->vtable_size;
        } else {
                /* General case */
 
@@ -5227,11 +5227,17 @@ mono_class_init (MonoClass *klass)
                if (!MONO_CLASS_IS_INTERFACE (klass) || klass->image != mono_defaults.corlib) {
                        MonoMethod *cmethod = NULL;
 
-                       if (klass->type_token && !image_is_dynamic(klass->image)) {
+                       if (mono_class_is_ginst (klass)) {
+                               MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
+
+                               /* Generic instance case */
+                               ghcimpl = gklass->ghcimpl;
+                               has_cctor = gklass->has_cctor;
+                       } else if (klass->type_token && !image_is_dynamic(klass->image)) {
                                cmethod = find_method_in_metadata (klass, ".cctor", 0, METHOD_ATTRIBUTE_SPECIAL_NAME);
                                /* The find_method function ignores the 'flags' argument */
                                if (cmethod && (cmethod->flags & METHOD_ATTRIBUTE_SPECIAL_NAME))
-                                       klass->has_cctor = 1;
+                                       has_cctor = 1;
                        } else {
                                mono_class_setup_methods (klass);
                                if (mono_class_has_failure (klass))
@@ -5241,7 +5247,7 @@ mono_class_init (MonoClass *klass)
                                        MonoMethod *method = klass->methods [i];
                                        if ((method->flags & METHOD_ATTRIBUTE_SPECIAL_NAME) && 
                                                (strcmp (".cctor", method->name) == 0)) {
-                                               klass->has_cctor = 1;
+                                               has_cctor = 1;
                                                break;
                                        }
                                }
@@ -5249,45 +5255,85 @@ mono_class_init (MonoClass *klass)
                }
        }
 
-       if (klass->parent) {
-               MonoError parent_error;
-               mono_error_init (&parent_error);
-               int first_iface_slot;
-               /* This will compute klass->parent->vtable_size for some classes */
-               mono_class_init (klass->parent);
-               if (mono_class_set_type_load_failure_causedby_class (klass, klass->parent, "Parent class failed to initialize")) {
-                       goto leave;
+       if (klass->rank) {
+               array_method_count = 3 + (klass->rank > 1? 2: 1);
+
+               if (klass->interface_count) {
+                       int count_generic = generic_array_methods (klass);
+                       array_method_count += klass->interface_count * count_generic;
                }
-               if (!klass->parent->vtable_size) {
-                       /* FIXME: Get rid of this somehow */
+       }
+
+       if (klass->parent) {
+               if (!klass->parent->vtable_size)
                        mono_class_setup_vtable (klass->parent);
-                       if (mono_class_set_type_load_failure_causedby_class (klass, klass->parent, "Parent class vtable failed to initialize")) {
-                               goto leave;
-                       }
-               }
+               if (mono_class_set_type_load_failure_causedby_class (klass, klass->parent, "Parent class vtable failed to initialize"))
+                       goto leave;
+               g_assert (klass->parent->vtable_size);
                first_iface_slot = klass->parent->vtable_size;
                if (mono_class_need_stelemref_method (klass))
                        ++first_iface_slot;
-               setup_interface_offsets (klass, first_iface_slot, TRUE);
-       } else {
-               setup_interface_offsets (klass, 0, TRUE);
        }
 
+       /*
+        * Do the actual changes to @klass inside the loader lock
+        */
+       mono_loader_lock ();
+       locked = TRUE;
+
+       if (klass->inited || mono_class_has_failure (klass)) {
+               mono_loader_unlock ();
+               /* Somebody might have gotten in before us */
+               return !mono_class_has_failure (klass);
+       }
+
+       mono_stats.initialized_class_count++;
+
+       if (mono_class_is_ginst (klass) && !mono_class_get_generic_class (klass)->is_dynamic) {
+               MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
+
+               mono_stats.generic_class_count++;
+
+               klass->method = gklass->method;
+               klass->field = gklass->field;
+       }
+
+       if (mono_class_is_ginst (klass) || image_is_dynamic (klass->image) || !klass->type_token || (has_cached_info && !cached_info.has_nested_classes))
+               klass->nested_classes_inited = TRUE;
+       klass->ghcimpl = ghcimpl;
+       klass->has_cctor = has_cctor;
+       if (vtable_size)
+               klass->vtable_size = vtable_size;
+       if (has_cached_info) {
+               klass->has_finalize = cached_info.has_finalize;
+               klass->has_finalize_inited = TRUE;
+       }
+       if (klass->rank)
+               klass->method.count = array_method_count;
+
+       mono_loader_unlock ();
+       locked = FALSE;
+
+       setup_interface_offsets (klass, first_iface_slot, TRUE);
+
        if (mono_security_core_clr_enabled ())
                mono_security_core_clr_check_inheritance (klass);
 
-       if (klass->generic_class && !mono_verifier_class_is_valid_generic_instantiation (klass))
+       if (mono_class_is_ginst (klass) && !mono_verifier_class_is_valid_generic_instantiation (klass))
                mono_class_set_type_load_failure (klass, "Invalid generic instantiation");
 
        goto leave;
 
  leave:
+       init_list = g_slist_remove (init_list, klass);
+       mono_native_tls_set_value (init_pending_tls_id, init_list);
+
        /* Because of the double-checking locking pattern */
        mono_memory_barrier ();
        klass->inited = 1;
-       klass->init_pending = 0;
 
-       mono_loader_unlock ();
+       if (locked)
+               mono_loader_unlock ();
 
        return !mono_class_has_failure (klass);
 }
@@ -5311,8 +5357,8 @@ mono_class_has_finalizer (MonoClass *klass)
                MonoMethod *cmethod = NULL;
 
                if (klass->rank == 1 && klass->byval_arg.type == MONO_TYPE_SZARRAY) {
-               } else if (klass->generic_class) {
-                       MonoClass *gklass = klass->generic_class->container_class;
+               } else if (mono_class_is_ginst (klass)) {
+                       MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
 
                        has_finalize = mono_class_has_finalizer (gklass);
                } else if (klass->parent && klass->parent->has_finalize) {
@@ -5489,7 +5535,6 @@ mono_class_setup_mono_type (MonoClass *klass)
 
        if (MONO_CLASS_IS_INTERFACE (klass))
                klass->interface_id = mono_get_unique_iid (klass);
-
 }
 
 #ifndef DISABLE_COM
@@ -5559,7 +5604,7 @@ mono_class_setup_parent (MonoClass *klass, MonoClass *parent)
 
                klass->parent = parent;
 
-               if (parent->generic_class && !parent->name) {
+               if (mono_class_is_ginst (parent) && !parent->name) {
                        /*
                         * If the parent is a generic instance, we may get
                         * called before it is fully initialized, especially
@@ -5659,7 +5704,7 @@ fix_gclass_incomplete_instantiation (MonoClass *gclass, void *user_data)
 {
        MonoClass *gtd = (MonoClass*)user_data;
        /* Only try to fix generic instances of @gtd */
-       if (gclass->generic_class->container_class != gtd)
+       if (mono_class_get_generic_class (gclass)->container_class != gtd)
                return FALSE;
 
        /* Check if the generic instance has no parent. */
@@ -5721,7 +5766,17 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError
        name = mono_metadata_string_heap (image, cols [MONO_TYPEDEF_NAME]);
        nspace = mono_metadata_string_heap (image, cols [MONO_TYPEDEF_NAMESPACE]);
 
-       klass = (MonoClass *)mono_image_alloc0 (image, sizeof (MonoClass));
+       if (mono_metadata_has_generic_params (image, type_token)) {
+               klass = mono_image_alloc0 (image, sizeof (MonoClassGtd));
+               klass->class_kind = MONO_CLASS_GTD;
+               classes_size += sizeof (MonoClassGtd);
+               ++class_gtd_count;
+       } else {
+               klass = mono_image_alloc0 (image, sizeof (MonoClassDef));
+               klass->class_kind = MONO_CLASS_DEF;
+               classes_size += sizeof (MonoClassDef);
+               ++class_def_count;
+       }
 
        klass->name = name;
        klass->name_space = nspace;
@@ -5730,25 +5785,21 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError
 
        klass->image = image;
        klass->type_token = type_token;
-       klass->flags = cols [MONO_TYPEDEF_FLAGS];
+       mono_class_set_flags (klass, cols [MONO_TYPEDEF_FLAGS]);
 
        mono_internal_hash_table_insert (&image->class_cache, GUINT_TO_POINTER (type_token), klass);
 
-       classes_size += sizeof (MonoClass);
-
        /*
         * Check whether we're a generic type definition.
         */
-       klass->generic_container = mono_metadata_load_generic_params (image, klass->type_token, NULL);
-       if (klass->generic_container) {
-               klass->is_generic = 1;
-               klass->generic_container->owner.klass = klass;
-               klass->generic_container->is_anonymous = FALSE; // Owner class is now known, container is no longer anonymous
-               context = &klass->generic_container->context;
-       }
-
-       if (klass->generic_container)
+       if (mono_class_is_gtd (klass)) {
+               MonoGenericContainer *generic_container = mono_metadata_load_generic_params (image, klass->type_token, NULL);
+               generic_container->owner.klass = klass;
+               generic_container->is_anonymous = FALSE; // Owner class is now known, container is no longer anonymous
+               context = &generic_container->context;
+               mono_class_set_generic_container (klass, generic_container);
                enable_gclass_recording ();
+       }
 
        if (cols [MONO_TYPEDEF_EXTENDS]) {
                MonoClass *tmp;
@@ -5776,7 +5827,7 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError
                                mono_class_set_failure_and_error (klass, error, "Cycle found while resolving parent");
                                goto parent_failure;
                        }
-                       if (klass->generic_container && tmp->generic_class && tmp->generic_class->container_class == klass) {
+                       if (mono_class_is_gtd (klass) && mono_class_is_ginst (tmp) && mono_class_get_generic_class (tmp)->container_class == klass) {
                                mono_class_set_failure_and_error (klass, error, "Parent extends generic instance of this type");
                                goto parent_failure;
                        }
@@ -5788,7 +5839,7 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError
        /* uses ->valuetype, which is initialized by mono_class_setup_parent above */
        mono_class_setup_mono_type (klass);
 
-       if (klass->generic_container)
+       if (mono_class_is_gtd (klass))
                disable_gclass_recording (fix_gclass_incomplete_instantiation, klass);
 
        /* 
@@ -5806,11 +5857,11 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError
                }
        }
 
-       if ((klass->flags & TYPE_ATTRIBUTE_STRING_FORMAT_MASK) == TYPE_ATTRIBUTE_UNICODE_CLASS)
+       if ((mono_class_get_flags (klass) & TYPE_ATTRIBUTE_STRING_FORMAT_MASK) == TYPE_ATTRIBUTE_UNICODE_CLASS)
                klass->unicode = 1;
 
 #ifdef HOST_WIN32
-       if ((klass->flags & TYPE_ATTRIBUTE_STRING_FORMAT_MASK) == TYPE_ATTRIBUTE_AUTO_CLASS)
+       if ((mono_class_get_flags (klass) & TYPE_ATTRIBUTE_STRING_FORMAT_MASK) == TYPE_ATTRIBUTE_AUTO_CLASS)
                klass->unicode = 1;
 #endif
 
@@ -5826,6 +5877,9 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError
                        return NULL;
                }
 
+               /* This is required now that it is possible for more than 2^16 interfaces to exist. */
+               g_assert(icount <= 65535);
+
                klass->interfaces = interfaces;
                klass->interface_count = icount;
                klass->interfaces_inited = 1;
@@ -5836,8 +5890,10 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError
        /*
         * Compute the field and method lists
         */
-       klass->field.first  = cols [MONO_TYPEDEF_FIELD_LIST] - 1;
-       klass->method.first = cols [MONO_TYPEDEF_METHOD_LIST] - 1;
+       int first_field_idx = cols [MONO_TYPEDEF_FIELD_LIST] - 1;
+       mono_class_set_first_field_idx (klass, first_field_idx);
+       int first_method_idx = cols [MONO_TYPEDEF_METHOD_LIST] - 1;
+       mono_class_set_first_method_idx (klass, first_method_idx);
 
        if (tt->rows > tidx){           
                mono_metadata_decode_row (tt, tidx, cols_next, MONO_TYPEDEF_SIZE);
@@ -5850,12 +5906,12 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError
 
        if (cols [MONO_TYPEDEF_FIELD_LIST] && 
            cols [MONO_TYPEDEF_FIELD_LIST] <= image->tables [MONO_TABLE_FIELD].rows)
-               klass->field.count = field_last - klass->field.first;
+               klass->field.count = field_last - first_field_idx;
        else
                klass->field.count = 0;
 
        if (cols [MONO_TYPEDEF_METHOD_LIST] <= image->tables [MONO_TABLE_METHOD].rows)
-               klass->method.count = method_last - klass->method.first;
+               klass->method.count = method_last - first_method_idx;
        else
                klass->method.count = 0;
 
@@ -5883,7 +5939,7 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError
         * We must do this after the class has been constructed to make certain recursive scenarios
         * work.
         */
-       if (klass->generic_container && !mono_metadata_load_generic_param_constraints_checked (image, type_token, klass->generic_container, error)) {
+       if (mono_class_is_gtd (klass) && !mono_metadata_load_generic_param_constraints_checked (image, type_token, mono_class_get_generic_container (klass), error)) {
                mono_class_set_type_load_failure (klass, "Could not load generic parameter constrains due to %s", mono_error_get_message (error));
                mono_loader_unlock ();
                mono_profiler_class_loaded (klass, MONO_PROFILE_FAILED);
@@ -5912,8 +5968,8 @@ parent_failure:
 gboolean
 mono_class_is_nullable (MonoClass *klass)
 {
-       return klass->generic_class != NULL &&
-               klass->generic_class->container_class == mono_defaults.generic_nullable_class;
+       MonoGenericClass *gklass = mono_class_try_get_generic_class (klass);
+       return gklass && gklass->container_class == mono_defaults.generic_nullable_class;
 }
 
 
@@ -5922,7 +5978,7 @@ MonoClass*
 mono_class_get_nullable_param (MonoClass *klass)
 {
        g_assert (mono_class_is_nullable (klass));
-       return mono_class_from_mono_type (klass->generic_class->context.class_inst->type_argv [0]);
+       return mono_class_from_mono_type (mono_class_get_generic_class (klass)->context.class_inst->type_argv [0]);
 }
 
 static void
@@ -5930,7 +5986,7 @@ mono_generic_class_setup_parent (MonoClass *klass, MonoClass *gtd)
 {
        if (gtd->parent) {
                MonoError error;
-               MonoGenericClass *gclass = klass->generic_class;
+               MonoGenericClass *gclass = mono_class_get_generic_class (klass);
 
                klass->parent = mono_class_inflate_generic_class_checked (gtd->parent, mono_generic_class_get_context (gclass), &error);
                if (!mono_error_ok (&error)) {
@@ -5968,7 +6024,7 @@ mono_generic_class_get_class (MonoGenericClass *gclass)
                return gclass->cached_class;
        }
 
-       klass = (MonoClass *)mono_image_set_alloc0 (gclass->owner, sizeof (MonoClass));
+       klass = (MonoClass *)mono_image_set_alloc0 (gclass->owner, sizeof (MonoClassGenericInst));
 
        gklass = gclass->container_class;
 
@@ -5986,12 +6042,12 @@ mono_generic_class_get_class (MonoGenericClass *gclass)
        mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD);
        
        klass->image = gklass->image;
-       klass->flags = gklass->flags;
        klass->type_token = gklass->type_token;
        klass->field.count = gklass->field.count;
 
-       klass->is_inflated = 1;
-       klass->generic_class = gclass;
+       klass->class_kind = MONO_CLASS_GINST;
+       //FIXME add setter
+       ((MonoClassGenericInst*)klass)->generic_class = gclass;
 
        klass->byval_arg.type = MONO_TYPE_GENERICINST;
        klass->this_arg.type = klass->byval_arg.type;
@@ -6041,8 +6097,8 @@ mono_generic_class_get_class (MonoGenericClass *gclass)
 
        mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
 
-       inflated_classes ++;
-       inflated_classes_size += sizeof (MonoClass);
+       ++class_ginst_count;
+       inflated_classes_size += sizeof (MonoClassGenericInst);
        
        mono_loader_unlock ();
 
@@ -6103,8 +6159,10 @@ make_generic_param_class (MonoGenericParam *param, MonoGenericParamInfo *pinfo)
        gboolean is_mvar = container->is_method;
        gboolean is_anonymous = container->is_anonymous;
 
-       klass = (MonoClass *)mono_image_alloc0 (image, sizeof (MonoClass));
-       classes_size += sizeof (MonoClass);
+       klass = (MonoClass *)mono_image_alloc0 (image, sizeof (MonoClassGenericParam));
+       klass->class_kind = MONO_CLASS_GPARAM;
+       classes_size += sizeof (MonoClassGenericParam);
+       ++class_gparam_count;
 
        if (pinfo) {
                CHECKED_METADATA_WRITE_PTR_EXEMPT ( klass->name , pinfo->name );
@@ -6154,7 +6212,6 @@ make_generic_param_class (MonoGenericParam *param, MonoGenericParamInfo *pinfo)
        klass->inited = TRUE;
        CHECKED_METADATA_WRITE_PTR_LOCAL ( klass->cast_class ,    klass );
        CHECKED_METADATA_WRITE_PTR_LOCAL ( klass->element_class , klass );
-       klass->flags = TYPE_ATTRIBUTE_PUBLIC;
 
        klass->byval_arg.type = is_mvar ? MONO_TYPE_MVAR : MONO_TYPE_VAR;
        klass->this_arg.type = klass->byval_arg.type;
@@ -6380,21 +6437,22 @@ mono_ptr_class_get (MonoType *type)
        }
        mono_image_unlock (image);
        
-       result = (MonoClass *)mono_image_alloc0 (image, sizeof (MonoClass));
+       result = (MonoClass *)mono_image_alloc0 (image, sizeof (MonoClassPointer));
 
-       classes_size += sizeof (MonoClass);
+       classes_size += sizeof (MonoClassPointer);
+       ++class_pointer_count;
 
        result->parent = NULL; /* no parent for PTR types */
        result->name_space = el_class->name_space;
        name = g_strdup_printf ("%s*", el_class->name);
        result->name = mono_image_strdup (image, name);
+       result->class_kind = MONO_CLASS_POINTER;
        g_free (name);
 
        mono_profiler_class_event (result, MONO_PROFILE_START_LOAD);
 
        result->image = el_class->image;
        result->inited = TRUE;
-       result->flags = TYPE_ATTRIBUTE_CLASS | (el_class->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK);
        result->instance_size = sizeof (MonoObject) + sizeof (gpointer);
        result->cast_class = result->element_class = el_class;
        result->blittable = TRUE;
@@ -6444,15 +6502,18 @@ mono_fnptr_class_get (MonoMethodSignature *sig)
        }
        result = g_new0 (MonoClass, 1);
 
+       classes_size += sizeof (MonoClassPointer);
+       ++class_pointer_count;
+
        result->parent = NULL; /* no parent for PTR types */
        result->name_space = "System";
        result->name = "MonoFNPtrFakeClass";
+       result->class_kind = MONO_CLASS_POINTER;
 
        mono_profiler_class_event (result, MONO_PROFILE_START_LOAD);
 
        result->image = mono_defaults.corlib; /* need to fix... */
        result->inited = TRUE;
-       result->flags = TYPE_ATTRIBUTE_CLASS; /* | (el_class->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK); */
        result->instance_size = sizeof (MonoObject) + sizeof (gpointer);
        result->cast_class = result->element_class = result;
        result->blittable = TRUE;
@@ -6659,10 +6720,12 @@ mono_bounded_array_class_get (MonoClass *eclass, guint32 rank, gboolean bounded)
        if (!parent->inited)
                mono_class_init (parent);
 
-       klass = (MonoClass *)mono_image_alloc0 (image, sizeof (MonoClass));
+       klass = (MonoClass *)mono_image_alloc0 (image, sizeof (MonoClassArray));
 
        klass->image = image;
        klass->name_space = eclass->name_space;
+       klass->class_kind = MONO_CLASS_ARRAY;
+
        nsize = strlen (eclass->name);
        name = (char *)g_malloc (nsize + 2 + rank + 1);
        memcpy (name, eclass->name, nsize);
@@ -6678,11 +6741,10 @@ mono_bounded_array_class_get (MonoClass *eclass, guint32 rank, gboolean bounded)
 
        mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD);
 
-       classes_size += sizeof (MonoClass);
+       classes_size += sizeof (MonoClassArray);
+       ++class_array_count;
 
        klass->type_token = 0;
-       /* all arrays are marked serializable and sealed, bug #42779 */
-       klass->flags = TYPE_ATTRIBUTE_CLASS | TYPE_ATTRIBUTE_SERIALIZABLE | TYPE_ATTRIBUTE_SEALED | TYPE_ATTRIBUTE_PUBLIC;
        klass->parent = parent;
        klass->instance_size = mono_class_instance_size (klass->parent);
 
@@ -6705,7 +6767,7 @@ mono_bounded_array_class_get (MonoClass *eclass, guint32 rank, gboolean bounded)
 
        mono_class_setup_supertypes (klass);
 
-       if (eclass->generic_class)
+       if (mono_class_is_ginst (eclass))
                mono_class_init (eclass);
        if (!eclass->size_inited)
                mono_class_setup_fields (eclass);
@@ -6762,7 +6824,8 @@ mono_bounded_array_class_get (MonoClass *eclass, guint32 rank, gboolean bounded)
        klass->this_arg = klass->byval_arg;
        klass->this_arg.byref = 1;
 
-       klass->generic_container = eclass->generic_container;
+       //WTF was this? it's wrong
+       // klass->generic_container = eclass->generic_container;
 
        if (rank == 1 && !bounded) {
                MonoClass *prev_class;
@@ -6824,7 +6887,7 @@ mono_class_instance_size (MonoClass *klass)
  *
  * Use to get the computed minimum alignment requirements for the specified class.
  *
- * Returns: minimm alignment requirements 
+ * Returns: minimum alignment requirements
  */
 gint32
 mono_class_min_align (MonoClass *klass)
@@ -6845,7 +6908,7 @@ mono_class_min_align (MonoClass *klass)
  * Returns: the size of a value of kind @klass
  */
 gint32
-mono_class_value_size      (MonoClass *klass, guint32 *align)
+mono_class_value_size (MonoClass *klass, guint32 *align)
 {
        gint32 size;
 
@@ -6898,9 +6961,10 @@ mono_class_get_field_idx (MonoClass *klass, int idx)
                return NULL;
 
        while (klass) {
+               int first_field_idx = mono_class_get_first_field_idx (klass);
                if (klass->image->uncompressed_metadata) {
                        /* 
-                        * klass->field.first points to the FieldPtr table, while idx points into the
+                        * first_field_idx points to the FieldPtr table, while idx points into the
                         * Field table, so we have to do a search.
                         */
                        /*FIXME this is broken for types with multiple fields with the same name.*/
@@ -6913,8 +6977,8 @@ mono_class_get_field_idx (MonoClass *klass, int idx)
                        g_assert_not_reached ();
                } else {                        
                        if (klass->field.count) {
-                               if ((idx >= klass->field.first) && (idx < klass->field.first + klass->field.count)){
-                                       return &klass->fields [idx - klass->field.first];
+                               if ((idx >= first_field_idx) && (idx < first_field_idx + klass->field.count)){
+                                       return &klass->fields [idx - first_field_idx];
                                }
                        }
                }
@@ -7018,9 +7082,10 @@ mono_class_get_field_token (MonoClassField *field)
        while (klass) {
                if (!klass->fields)
                        return 0;
+               int first_field_idx = mono_class_get_first_field_idx (klass);
                for (i = 0; i < klass->field.count; ++i) {
                        if (&klass->fields [i] == field) {
-                               int idx = klass->field.first + i + 1;
+                               int idx = first_field_idx + i + 1;
 
                                if (klass->image->uncompressed_metadata)
                                        idx = mono_metadata_translate_token_index (klass->image, MONO_TABLE_FIELD, idx);
@@ -8064,10 +8129,10 @@ mono_class_has_variant_generic_params (MonoClass *klass)
        int i;
        MonoGenericContainer *container;
 
-       if (!klass->generic_class)
+       if (!mono_class_is_ginst (klass))
                return FALSE;
 
-       container = klass->generic_class->container_class->generic_container;
+       container = mono_class_get_generic_container (mono_class_get_generic_class (klass)->container_class);
 
        for (i = 0; i < container->type_argc; ++i)
                if (mono_generic_container_get_param_info (container, i)->flags & (MONO_GEN_PARAM_VARIANT|MONO_GEN_PARAM_COVARIANT))
@@ -8111,7 +8176,7 @@ mono_class_is_variant_compatible (MonoClass *klass, MonoClass *oklass, gboolean
        int j;
        MonoType **klass_argv, **oklass_argv;
        MonoClass *klass_gtd = mono_class_get_generic_type_definition (klass);
-       MonoGenericContainer *container = klass_gtd->generic_container;
+       MonoGenericContainer *container = mono_class_get_generic_container (klass_gtd);
 
        if (klass == oklass)
                return TRUE;
@@ -8120,8 +8185,8 @@ mono_class_is_variant_compatible (MonoClass *klass, MonoClass *oklass, gboolean
        if (mono_class_get_generic_type_definition (oklass) != klass_gtd || oklass == klass_gtd)
                return FALSE;
 
-       klass_argv = &klass->generic_class->context.class_inst->type_argv [0];
-       oklass_argv = &oklass->generic_class->context.class_inst->type_argv [0];
+       klass_argv = &mono_class_get_generic_class (klass)->context.class_inst->type_argv [0];
+       oklass_argv = &mono_class_get_generic_class (oklass)->context.class_inst->type_argv [0];
 
        for (j = 0; j < container->type_argc; ++j) {
                MonoClass *param1_class = mono_class_from_mono_type (klass_argv [j]);
@@ -8376,14 +8441,14 @@ mono_class_is_variant_compatible_slow (MonoClass *klass, MonoClass *oklass)
        int j;
        MonoType **klass_argv, **oklass_argv;
        MonoClass *klass_gtd = mono_class_get_generic_type_definition (klass);
-       MonoGenericContainer *container = klass_gtd->generic_container;
+       MonoGenericContainer *container = mono_class_get_generic_container (klass_gtd);
 
        /*Viable candidates are instances of the same generic interface*/
        if (mono_class_get_generic_type_definition (oklass) != klass_gtd || oklass == klass_gtd)
                return FALSE;
 
-       klass_argv = &klass->generic_class->context.class_inst->type_argv [0];
-       oklass_argv = &oklass->generic_class->context.class_inst->type_argv [0];
+       klass_argv = &mono_class_get_generic_class (klass)->context.class_inst->type_argv [0];
+       oklass_argv = &mono_class_get_generic_class (oklass)->context.class_inst->type_argv [0];
 
        for (j = 0; j < container->type_argc; ++j) {
                MonoClass *param1_class = mono_class_from_mono_type (klass_argv [j]);
@@ -8560,8 +8625,8 @@ mono_class_get_cctor (MonoClass *klass)
                return result;
        }
 
-       if (klass->generic_class && !klass->methods)
-               return mono_class_get_inflated_method (klass, mono_class_get_cctor (klass->generic_class->container_class));
+       if (mono_class_is_ginst (klass) && !klass->methods)
+               return mono_class_get_inflated_method (klass, mono_class_get_cctor (mono_class_get_generic_class (klass)->container_class));
 
        return mono_class_get_method_from_name_flags (klass, ".cctor", -1, METHOD_ATTRIBUTE_SPECIAL_NAME);
 }
@@ -8942,22 +9007,6 @@ mono_class_get_rank (MonoClass *klass)
        return klass->rank;
 }
 
-/**
- * mono_class_get_flags:
- * @klass: the MonoClass to act on
- *
- * The type flags from the TypeDef table from the metadata.
- * see the TYPE_ATTRIBUTE_* definitions on tabledefs.h for the
- * different values.
- *
- * Returns: The flags from the TypeDef table.
- */
-guint32
-mono_class_get_flags (MonoClass *klass)
-{
-       return klass->flags;
-}
-
 /**
  * mono_class_get_name
  * @klass: the MonoClass to act on
@@ -9209,11 +9258,12 @@ mono_class_get_virtual_methods (MonoClass* klass, gpointer *iter)
                        start_index = GPOINTER_TO_UINT (*iter);
                }
 
+               int first_idx = mono_class_get_first_method_idx (klass);
                for (i = start_index; i < klass->method.count; ++i) {
                        guint32 flags;
 
-                       /* klass->method.first points into the methodptr table */
-                       flags = mono_metadata_decode_table_row_col (klass->image, MONO_TABLE_METHOD, klass->method.first + i, MONO_METHOD_FLAGS);
+                       /* first_idx points into the methodptr table */
+                       flags = mono_metadata_decode_table_row_col (klass->image, MONO_TABLE_METHOD, first_idx + i, MONO_METHOD_FLAGS);
 
                        if (flags & METHOD_ATTRIBUTE_VIRTUAL)
                                break;
@@ -9221,7 +9271,7 @@ mono_class_get_virtual_methods (MonoClass* klass, gpointer *iter)
 
                if (i < klass->method.count) {
                        MonoError error;
-                       res = mono_get_method_checked (klass->image, MONO_TOKEN_METHOD_DEF | (klass->method.first + i + 1), klass, NULL, &error);
+                       res = mono_get_method_checked (klass->image, MONO_TOKEN_METHOD_DEF | (first_idx + i + 1), klass, NULL, &error);
                        mono_error_cleanup (&error); /* FIXME don't swallow the error */
 
                        /* Add 1 here so the if (*iter) check fails */
@@ -9588,7 +9638,8 @@ mono_field_get_rva (MonoClassField *field)
        field_index = mono_field_get_index (field);
                
        if (!klass->ext->field_def_values [field_index].data && !image_is_dynamic (klass->image)) {
-               mono_metadata_field_info (field->parent->image, klass->field.first + field_index, NULL, &rva, NULL);
+               int first_field_idx = mono_class_get_first_field_idx (klass);
+               mono_metadata_field_info (field->parent->image, first_field_idx + field_index, NULL, &rva, NULL);
                if (!rva)
                        g_warning ("field %s in %s should have RVA data, but hasn't", mono_field_get_name (field), field->parent->name);
                klass->ext->field_def_values [field_index].data = mono_image_rva_map (field->parent->image, rva);
@@ -9778,17 +9829,18 @@ find_method_in_metadata (MonoClass *klass, const char *name, int param_count, in
        int i;
 
        /* Search directly in the metadata to avoid calling setup_methods () */
+       int first_idx = mono_class_get_first_method_idx (klass);
        for (i = 0; i < klass->method.count; ++i) {
                MonoError error;
                guint32 cols [MONO_METHOD_SIZE];
                MonoMethod *method;
                MonoMethodSignature *sig;
 
-               /* klass->method.first points into the methodptr table */
-               mono_metadata_decode_table_row (klass->image, MONO_TABLE_METHOD, klass->method.first + i, cols, MONO_METHOD_SIZE);
+               /* first_idx points into the methodptr table */
+               mono_metadata_decode_table_row (klass->image, MONO_TABLE_METHOD, first_idx + i, cols, MONO_METHOD_SIZE);
 
                if (!strcmp (mono_metadata_string_heap (klass->image, cols [MONO_METHOD_NAME]), name)) {
-                       method = mono_get_method_checked (klass->image, MONO_TOKEN_METHOD_DEF | (klass->method.first + i + 1), klass, NULL, &error);
+                       method = mono_get_method_checked (klass->image, MONO_TOKEN_METHOD_DEF | (first_idx + i + 1), klass, NULL, &error);
                        if (!method) {
                                mono_error_cleanup (&error); /* FIXME don't swallow the error */
                                continue;
@@ -9830,8 +9882,8 @@ mono_class_get_method_from_name_flags (MonoClass *klass, const char *name, int p
 
        mono_class_init (klass);
 
-       if (klass->generic_class && !klass->methods) {
-               res = mono_class_get_method_from_name_flags (klass->generic_class->container_class, name, param_count, flags);
+       if (mono_class_is_ginst (klass) && !klass->methods) {
+               res = mono_class_get_method_from_name_flags (mono_class_get_generic_class (klass)->container_class, name, param_count, flags);
                if (res) {
                        MonoError error;
                        res = mono_class_inflate_generic_method_full_checked (res, klass, mono_class_get_context (klass), &error);
@@ -9961,17 +10013,31 @@ mono_classes_init (void)
        mono_os_mutex_init (&classes_mutex);
 
        mono_native_tls_alloc (&setup_fields_tls_id, NULL);
-
+       mono_native_tls_alloc (&init_pending_tls_id, NULL);
+
+       mono_counters_register ("MonoClassDef count",
+                                                       MONO_COUNTER_METADATA | MONO_COUNTER_INT, &class_def_count);
+       mono_counters_register ("MonoClassGtd count",
+                                                       MONO_COUNTER_METADATA | MONO_COUNTER_INT, &class_gtd_count);
+       mono_counters_register ("MonoClassGenericInst count",
+                                                       MONO_COUNTER_METADATA | MONO_COUNTER_INT, &class_ginst_count);
+       mono_counters_register ("MonoClassGenericParam count",
+                                                       MONO_COUNTER_METADATA | MONO_COUNTER_INT, &class_gparam_count);
+       mono_counters_register ("MonoClassArray count",
+                                                       MONO_COUNTER_METADATA | MONO_COUNTER_INT, &class_array_count);
+       mono_counters_register ("MonoClassPointer count",
+                                                       MONO_COUNTER_METADATA | MONO_COUNTER_INT, &class_pointer_count);
        mono_counters_register ("Inflated methods size",
                                                        MONO_COUNTER_GENERICS | MONO_COUNTER_INT, &inflated_methods_size);
-       mono_counters_register ("Inflated classes",
-                                                       MONO_COUNTER_GENERICS | MONO_COUNTER_INT, &inflated_classes);
        mono_counters_register ("Inflated classes size",
                                                        MONO_COUNTER_GENERICS | MONO_COUNTER_INT, &inflated_classes_size);
        mono_counters_register ("MonoClass size",
                                                        MONO_COUNTER_METADATA | MONO_COUNTER_INT, &classes_size);
        mono_counters_register ("MonoClassExt size",
                                                        MONO_COUNTER_METADATA | MONO_COUNTER_INT, &class_ext_size);
+
+       mono_counters_register ("MonoClassExt count",
+                                                       MONO_COUNTER_METADATA | MONO_COUNTER_INT, &class_ext_count);
 }
 
 /**
@@ -9983,6 +10049,7 @@ void
 mono_classes_cleanup (void)
 {
        mono_native_tls_free (setup_fields_tls_id);
+       mono_native_tls_free (init_pending_tls_id);
 
        if (global_interface_bitset)
                mono_bitset_free (global_interface_bitset);
@@ -10025,7 +10092,8 @@ is_nesting_type (MonoClass *outer_klass, MonoClass *inner_klass)
 MonoClass *
 mono_class_get_generic_type_definition (MonoClass *klass)
 {
-       return klass->generic_class ? klass->generic_class->container_class : klass;
+       MonoGenericClass *gklass =  mono_class_try_get_generic_class (klass);
+       return gklass ? gklass->container_class : klass;
 }
 
 /*
@@ -10122,8 +10190,9 @@ static MonoClass*
 get_generic_definition_class (MonoClass *klass)
 {
        while (klass) {
-               if (klass->generic_class && klass->generic_class->container_class)
-                       return klass->generic_class->container_class;
+               MonoGenericClass *gklass = mono_class_try_get_generic_class (klass);
+               if (gklass && gklass->container_class)
+                       return gklass->container_class;
                klass = klass->parent;
        }
        return NULL;
@@ -10177,12 +10246,12 @@ can_access_type (MonoClass *access_klass, MonoClass *member_klass)
        if (member_klass->element_class && !member_klass->enumtype)
                member_klass = member_klass->element_class;
 
-       access_level = member_klass->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK;
+       access_level = mono_class_get_flags (member_klass) & TYPE_ATTRIBUTE_VISIBILITY_MASK;
 
        if (member_klass->byval_arg.type == MONO_TYPE_VAR || member_klass->byval_arg.type == MONO_TYPE_MVAR)
                return TRUE;
 
-       if (member_klass->generic_class && !can_access_instantiation (access_klass, member_klass->generic_class->context.class_inst))
+       if (mono_class_is_ginst (member_klass) && !can_access_instantiation (access_klass, mono_class_get_generic_class (member_klass)->context.class_inst))
                return FALSE;
 
        if (is_nesting_type (access_klass, member_klass) || (access_klass->nested_in && is_nesting_type (access_klass->nested_in, member_klass)))
@@ -10233,15 +10302,16 @@ can_access_member (MonoClass *access_klass, MonoClass *member_klass, MonoClass*
        if (access_klass->image->assembly && access_klass->image->assembly->corlib_internal)
                return TRUE;
 
-       if (((access_klass->generic_class && access_klass->generic_class->container_class) ||
-                                       access_klass->generic_container) && 
+       MonoGenericClass *access_gklass = mono_class_try_get_generic_class (access_klass);
+       if (((access_gklass && access_gklass->container_class) ||
+                                       mono_class_is_gtd (access_klass)) && 
                        (member_generic_def = get_generic_definition_class (member_klass))) {
                MonoClass *access_container;
 
-               if (access_klass->generic_container)
+               if (mono_class_is_gtd (access_klass))
                        access_container = access_klass;
                else
-                       access_container = access_klass->generic_class->container_class;
+                       access_container = access_gklass->container_class;
 
                if (can_access_member (access_container, member_generic_def, context_klass, access_level))
                        return TRUE;
@@ -10479,7 +10549,9 @@ gboolean mono_type_is_valid_enum_basetype (MonoType * type) {
  * FIXME: enum types are not allowed to have a cctor, but mono_reflection_create_runtime_class sets has_cctor to 1 for all types
  * FIXME: TypeBuilder enums can have any kind of static fields, but the spec is very explicit about that (P II 14.3)
  */
-gboolean mono_class_is_valid_enum (MonoClass *klass) {
+gboolean
+mono_class_is_valid_enum (MonoClass *klass)
+{
        MonoClassField * field;
        gpointer iter = NULL;
        gboolean found_base_field = FALSE;
@@ -10490,7 +10562,7 @@ gboolean mono_class_is_valid_enum (MonoClass *klass) {
                return FALSE;
        }
 
-       if ((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) != TYPE_ATTRIBUTE_AUTO_LAYOUT)
+       if (!mono_class_is_auto_layout (klass))
                return FALSE;
 
        while ((field = mono_class_get_fields (klass, &iter))) {
@@ -10515,7 +10587,7 @@ gboolean mono_class_is_valid_enum (MonoClass *klass) {
 gboolean
 mono_generic_class_is_generic_type_definition (MonoGenericClass *gklass)
 {
-       return gklass->context.class_inst == gklass->container_class->generic_container->context.class_inst;
+       return gklass->context.class_inst == mono_class_get_generic_container (gklass->container_class)->context.class_inst;
 }
 
 /*
@@ -10553,6 +10625,7 @@ mono_class_alloc_ext (MonoClass *klass)
        if (!klass->ext)
                klass->ext = ext;
        class_ext_size += sizeof (MonoClassExt);
+       ++class_ext_count;
        mono_image_unlock (klass->image);
 }
 
@@ -10587,8 +10660,8 @@ mono_class_setup_interfaces (MonoClass *klass, MonoError *error)
                if (interface_count > 1)
                        interfaces [1] = mono_class_bind_generic_parameters (
                           mono_defaults.generic_ireadonlylist_class, 1, args, FALSE);
-       } else if (klass->generic_class) {
-               MonoClass *gklass = klass->generic_class->container_class;
+       } else if (mono_class_is_ginst (klass)) {
+               MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
 
                mono_class_setup_interfaces (gklass, error);
                if (!mono_error_ok (error)) {
@@ -10599,7 +10672,7 @@ mono_class_setup_interfaces (MonoClass *klass, MonoError *error)
                interface_count = gklass->interface_count;
                interfaces = mono_class_new0 (klass, MonoClass *, interface_count);
                for (i = 0; i < interface_count; i++) {
-                       interfaces [i] = mono_class_inflate_generic_class_checked (gklass->interfaces [i], mono_generic_class_get_context (klass->generic_class), error);
+                       interfaces [i] = mono_class_inflate_generic_class_checked (gklass->interfaces [i], mono_generic_class_get_context (mono_class_get_generic_class (klass)), error);
                        if (!mono_error_ok (error)) {
                                mono_class_set_type_load_failure (klass, "Could not setup the interfaces");
                                return;
@@ -10629,7 +10702,7 @@ mono_field_resolve_type (MonoClassField *field, MonoError *error)
 {
        MonoClass *klass = field->parent;
        MonoImage *image = klass->image;
-       MonoClass *gtd = klass->generic_class ? mono_class_get_generic_type_definition (klass) : NULL;
+       MonoClass *gtd = mono_class_is_ginst (klass) ? mono_class_get_generic_type_definition (klass) : NULL;
        int field_idx = field - klass->fields;
 
        mono_error_init (error);
@@ -10638,35 +10711,41 @@ mono_field_resolve_type (MonoClassField *field, MonoError *error)
                MonoClassField *gfield = &gtd->fields [field_idx];
                MonoType *gtype = mono_field_get_type_checked (gfield, error);
                if (!mono_error_ok (error)) {
-                       mono_class_set_type_load_failure (klass, "Could not load field %d type due to: %s", field_idx, mono_error_get_message (error));
+                       char *full_name = mono_type_get_full_name (gtd);
+                       mono_class_set_type_load_failure (klass, "Could not load generic type of field '%s:%s' (%d) due to: %s", full_name, gfield->name, field_idx, mono_error_get_message (error));
+                       g_free (full_name);
                }
 
                field->type = mono_class_inflate_generic_type_no_copy (image, gtype, mono_class_get_context (klass), error);
                if (!mono_error_ok (error)) {
-                       mono_class_set_type_load_failure (klass, "Could not load field %d type due to: %s", field_idx, mono_error_get_message (error));
+                       char *full_name = mono_type_get_full_name (klass);
+                       mono_class_set_type_load_failure (klass, "Could not load instantiated type of field '%s:%s' (%d) due to: %s", full_name, field->name, field_idx, mono_error_get_message (error));
+                       g_free (full_name);
                }
        } else {
                const char *sig;
                guint32 cols [MONO_FIELD_SIZE];
                MonoGenericContainer *container = NULL;
-               int idx = klass->field.first + field_idx;
+               int idx = mono_class_get_first_field_idx (klass) + field_idx;
 
                /*FIXME, in theory we do not lazy load SRE fields*/
                g_assert (!image_is_dynamic (image));
 
-               if (klass->generic_container) {
-                       container = klass->generic_container;
+               if (mono_class_is_gtd (klass)) {
+                       container = mono_class_get_generic_container (klass);
                } else if (gtd) {
-                       container = gtd->generic_container;
+                       container = mono_class_get_generic_container (gtd);
                        g_assert (container);
                }
 
-               /* klass->field.first and idx points into the fieldptr table */
+               /* first_field_idx and idx points into the fieldptr table */
                mono_metadata_decode_table_row (image, MONO_TABLE_FIELD, idx, cols, MONO_FIELD_SIZE);
 
                if (!mono_verifier_verify_field_signature (image, cols [MONO_FIELD_SIGNATURE], NULL)) {
-                       mono_error_set_type_load_class (error, klass, "Could not verify field %s signature", field->name);;
+                       char *full_name = mono_type_get_full_name (klass);
+                       mono_error_set_type_load_class (error, klass, "Could not verify field '%s:%s' signature", full_name, field->name);;
                        mono_class_set_type_load_failure (klass, "%s", mono_error_get_message (error));
+                       g_free (full_name);
                        return;
                }
 
@@ -10678,7 +10757,9 @@ mono_field_resolve_type (MonoClassField *field, MonoError *error)
 
                field->type = mono_metadata_parse_type_checked (image, container, cols [MONO_FIELD_FLAGS], FALSE, sig + 1, &sig, error);
                if (!field->type) {
-                       mono_class_set_type_load_failure (klass, "Could not load field %d type due to: %s", field_idx, mono_error_get_message (error));
+                       char *full_name = mono_type_get_full_name (klass);
+                       mono_class_set_type_load_failure (klass, "Could not load type of field '%s:%s' (%d) due to: %s", full_name, field->name, field_idx, mono_error_get_message (error));
+                       g_free (full_name);
                }
        }
 }
@@ -10688,7 +10769,7 @@ mono_field_resolve_flags (MonoClassField *field)
 {
        MonoClass *klass = field->parent;
        MonoImage *image = klass->image;
-       MonoClass *gtd = klass->generic_class ? mono_class_get_generic_type_definition (klass) : NULL;
+       MonoClass *gtd = mono_class_is_ginst (klass) ? mono_class_get_generic_type_definition (klass) : NULL;
        int field_idx = field - klass->fields;
 
 
@@ -10696,7 +10777,7 @@ mono_field_resolve_flags (MonoClassField *field)
                MonoClassField *gfield = &gtd->fields [field_idx];
                return mono_field_get_flags (gfield);
        } else {
-               int idx = klass->field.first + field_idx;
+               int idx = mono_class_get_first_field_idx (klass) + field_idx;
 
                /*FIXME, in theory we do not lazy load SRE fields*/
                g_assert (!image_is_dynamic (image));
index 5f7d15560aa1c3c83d20b8664b7ae7cfe4517e34..c918d3787df79c18fc1741cfc5565c9afc7b0998 100644 (file)
@@ -1506,7 +1506,7 @@ ves_icall_System_Runtime_InteropServices_Marshal_ReleaseInternal (gpointer pUnk)
 
 static gboolean cominterop_can_support_dispatch (MonoClass* klass)
 {
-       if (!(klass->flags & TYPE_ATTRIBUTE_PUBLIC) )
+       if (!mono_class_is_public (klass))
                return FALSE;
 
        if (!cominterop_com_visible (klass))
index 2f93fecc8779134312080d1cc3e3026a8526ef9b..76bd1c21d8c1d94472af2886d8acc519d5afba0b 100644 (file)
@@ -7,4 +7,9 @@
 MonoCustomAttrInfo*
 mono_custom_attrs_from_builders (MonoImage *alloc_img, MonoImage *image, MonoArray *cattrs);
 
+typedef gboolean (*MonoAssemblyMetadataCustomAttrIterFunc) (MonoImage *image, guint32 typeref_scope_token, const gchar* nspace, const gchar* name, guint32 method_token, gpointer user_data);
+
+void
+mono_assembly_metadata_foreach_custom_attr (MonoAssembly *assembly, MonoAssemblyMetadataCustomAttrIterFunc func, gpointer user_data);
+
 #endif  /* __MONO_METADATA_REFLECTION_CUSTOM_ATTRS_INTERNALS_H__ */
index b30f3d8ef594b24682e5917cd318776d3784a96a..20fd8de75215b2b5ce726ba34a0ae9d763915c57 100644 (file)
@@ -12,6 +12,7 @@
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 #include <config.h>
+#include "mono/metadata/assembly.h"
 #include "mono/metadata/gc-internals.h"
 #include "mono/metadata/mono-endian.h"
 #include "mono/metadata/object-internals.h"
@@ -69,7 +70,7 @@ custom_attr_visible (MonoImage *image, MonoReflectionCustomAttr *cattr)
 
        /* FIXME: Need to do more checks */
        if (cattr->ctor->method && (cattr->ctor->method->klass->image != image)) {
-               int visibility = cattr->ctor->method->klass->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK;
+               int visibility = mono_class_get_flags (cattr->ctor->method->klass) & TYPE_ATTRIBUTE_VISIBILITY_MASK;
 
                if ((visibility != TYPE_ATTRIBUTE_PUBLIC) && (visibility != TYPE_ATTRIBUTE_NESTED_PUBLIC))
                        return FALSE;
@@ -121,7 +122,7 @@ find_field_index (MonoClass *klass, MonoClassField *field) {
 
        for (i = 0; i < klass->field.count; ++i) {
                if (field == &klass->fields [i])
-                       return klass->field.first + 1 + i;
+                       return mono_class_get_first_field_idx (klass) + 1 + i;
        }
        return 0;
 }
@@ -1072,7 +1073,7 @@ MonoCustomAttrInfo*
 mono_custom_attrs_from_index (MonoImage *image, guint32 idx)
 {
        MonoError error;
-       MonoCustomAttrInfo *result = mono_custom_attrs_from_index_checked (image, idx, &error);
+       MonoCustomAttrInfo *result = mono_custom_attrs_from_index_checked (image, idx, FALSE, &error);
        mono_error_cleanup (&error);
        return result;
 }
@@ -1082,7 +1083,7 @@ mono_custom_attrs_from_index (MonoImage *image, guint32 idx)
  * Returns: NULL if no attributes are found.  On error returns NULL and sets @error.
  */
 MonoCustomAttrInfo*
-mono_custom_attrs_from_index_checked (MonoImage *image, guint32 idx, MonoError *error)
+mono_custom_attrs_from_index_checked (MonoImage *image, guint32 idx, gboolean ignore_missing, MonoError *error)
 {
        guint32 mtoken, i, len;
        guint32 cols [MONO_CUSTOM_ATTR_SIZE];
@@ -1129,10 +1130,15 @@ mono_custom_attrs_from_index_checked (MonoImage *image, guint32 idx, MonoError *
                attr = &ainfo->attrs [i - 1];
                attr->ctor = mono_get_method_checked (image, mtoken, NULL, NULL, error);
                if (!attr->ctor) {
-                       g_warning ("Can't find custom attr constructor image: %s mtoken: 0x%08x due to %s", image->name, mtoken, mono_error_get_message (error));
-                       g_list_free (list);
-                       g_free (ainfo);
-                       return NULL;
+                       g_warning ("Can't find custom attr constructor image: %s mtoken: 0x%08x due to: %s", image->name, mtoken, mono_error_get_message (error));
+                       if (ignore_missing) {
+                               mono_error_cleanup (error);
+                               mono_error_init (error);
+                       } else {
+                               g_list_free (list);
+                               g_free (ainfo);
+                               return NULL;
+                       }
                }
 
                if (!mono_verifier_verify_cattr_blob (image, cols [MONO_CUSTOM_ATTR_VALUE], NULL)) {
@@ -1186,7 +1192,7 @@ mono_custom_attrs_from_method_checked (MonoMethod *method, MonoError *error)
        idx = mono_method_get_index (method);
        idx <<= MONO_CUSTOM_ATTR_BITS;
        idx |= MONO_CUSTOM_ATTR_METHODDEF;
-       return mono_custom_attrs_from_index_checked (method->klass->image, idx, error);
+       return mono_custom_attrs_from_index_checked (method->klass->image, idx, FALSE, error);
 }
 
 MonoCustomAttrInfo*
@@ -1205,8 +1211,8 @@ mono_custom_attrs_from_class_checked (MonoClass *klass, MonoError *error)
 
        mono_error_init (error);
 
-       if (klass->generic_class)
-               klass = klass->generic_class->container_class;
+       if (mono_class_is_ginst (klass))
+               klass = mono_class_get_generic_class (klass)->container_class;
 
        if (image_is_dynamic (klass->image))
                return lookup_custom_attr (klass->image, klass);
@@ -1220,20 +1226,20 @@ mono_custom_attrs_from_class_checked (MonoClass *klass, MonoError *error)
                idx <<= MONO_CUSTOM_ATTR_BITS;
                idx |= MONO_CUSTOM_ATTR_TYPEDEF;
        }
-       return mono_custom_attrs_from_index_checked (klass->image, idx, error);
+       return mono_custom_attrs_from_index_checked (klass->image, idx, FALSE, error);
 }
 
 MonoCustomAttrInfo*
 mono_custom_attrs_from_assembly (MonoAssembly *assembly)
 {
        MonoError error;
-       MonoCustomAttrInfo *result = mono_custom_attrs_from_assembly_checked (assembly, &error);
+       MonoCustomAttrInfo *result = mono_custom_attrs_from_assembly_checked (assembly, FALSE, &error);
        mono_error_cleanup (&error);
        return result;
 }
 
 MonoCustomAttrInfo*
-mono_custom_attrs_from_assembly_checked (MonoAssembly *assembly, MonoError *error)
+mono_custom_attrs_from_assembly_checked (MonoAssembly *assembly, gboolean ignore_missing, MonoError *error)
 {
        guint32 idx;
        
@@ -1244,7 +1250,7 @@ mono_custom_attrs_from_assembly_checked (MonoAssembly *assembly, MonoError *erro
        idx = 1; /* there is only one assembly */
        idx <<= MONO_CUSTOM_ATTR_BITS;
        idx |= MONO_CUSTOM_ATTR_ASSEMBLY;
-       return mono_custom_attrs_from_index_checked (assembly->image, idx, error);
+       return mono_custom_attrs_from_index_checked (assembly->image, idx, ignore_missing, error);
 }
 
 static MonoCustomAttrInfo*
@@ -1257,7 +1263,7 @@ mono_custom_attrs_from_module (MonoImage *image, MonoError *error)
        idx = 1; /* there is only one module */
        idx <<= MONO_CUSTOM_ATTR_BITS;
        idx |= MONO_CUSTOM_ATTR_MODULE;
-       return mono_custom_attrs_from_index_checked (image, idx, error);
+       return mono_custom_attrs_from_index_checked (image, idx, FALSE, error);
 }
 
 MonoCustomAttrInfo*
@@ -1281,7 +1287,7 @@ mono_custom_attrs_from_property_checked (MonoClass *klass, MonoProperty *propert
        idx = find_property_index (klass, property);
        idx <<= MONO_CUSTOM_ATTR_BITS;
        idx |= MONO_CUSTOM_ATTR_PROPERTY;
-       return mono_custom_attrs_from_index_checked (klass->image, idx, error);
+       return mono_custom_attrs_from_index_checked (klass->image, idx, FALSE, error);
 }
 
 MonoCustomAttrInfo*
@@ -1305,7 +1311,7 @@ mono_custom_attrs_from_event_checked (MonoClass *klass, MonoEvent *event, MonoEr
        idx = find_event_index (klass, event);
        idx <<= MONO_CUSTOM_ATTR_BITS;
        idx |= MONO_CUSTOM_ATTR_EVENT;
-       return mono_custom_attrs_from_index_checked (klass->image, idx, error);
+       return mono_custom_attrs_from_index_checked (klass->image, idx, FALSE, error);
 }
 
 MonoCustomAttrInfo*
@@ -1330,7 +1336,7 @@ mono_custom_attrs_from_field_checked (MonoClass *klass, MonoClassField *field, M
        idx = find_field_index (klass, field);
        idx <<= MONO_CUSTOM_ATTR_BITS;
        idx |= MONO_CUSTOM_ATTR_FIELDDEF;
-       return mono_custom_attrs_from_index_checked (klass->image, idx, error);
+       return mono_custom_attrs_from_index_checked (klass->image, idx, FALSE, error);
 }
 
 /**
@@ -1426,7 +1432,7 @@ mono_custom_attrs_from_param_checked (MonoMethod *method, guint32 param, MonoErr
        idx = i;
        idx <<= MONO_CUSTOM_ATTR_BITS;
        idx |= MONO_CUSTOM_ATTR_PARAMDEF;
-       return mono_custom_attrs_from_index_checked (image, idx, error);
+       return mono_custom_attrs_from_index_checked (image, idx, FALSE, error);
 }
 
 gboolean
@@ -1525,7 +1531,7 @@ mono_reflection_get_custom_attrs_info_checked (MonoObject *obj, MonoError *error
                return_val_if_nok (error, NULL);
        } else if (strcmp ("Assembly", klass->name) == 0 || strcmp ("MonoAssembly", klass->name) == 0) {
                MonoReflectionAssembly *rassembly = (MonoReflectionAssembly*)obj;
-               cinfo = mono_custom_attrs_from_assembly_checked (rassembly->assembly, error);
+               cinfo = mono_custom_attrs_from_assembly_checked (rassembly->assembly, FALSE, error);
                return_val_if_nok (error, NULL);
        } else if (strcmp ("Module", klass->name) == 0 || strcmp ("MonoModule", klass->name) == 0) {
                MonoReflectionModule *module = (MonoReflectionModule*)obj;
@@ -1705,3 +1711,174 @@ mono_reflection_get_custom_attrs_data_checked (MonoObject *obj, MonoError *error
 
        return result;
 }
+
+static gboolean
+custom_attr_class_name_from_methoddef (MonoImage *image, guint32 method_token, const gchar **nspace, const gchar **class_name)
+{
+       /* mono_get_method_from_token () */
+       g_assert (mono_metadata_token_table (method_token) == MONO_TABLE_METHOD);
+       guint32 type_token = mono_metadata_typedef_from_method (image, method_token);
+       if (!type_token) {
+               /* Bad method token (could not find corresponding typedef) */
+               return FALSE;
+       }
+       type_token |= MONO_TOKEN_TYPE_DEF;
+       {
+               /* mono_class_create_from_typedef () */
+               MonoTableInfo *tt = &image->tables [MONO_TABLE_TYPEDEF];
+               guint32 cols [MONO_TYPEDEF_SIZE];
+               guint tidx = mono_metadata_token_index (type_token);
+
+               if (mono_metadata_token_table (type_token) != MONO_TABLE_TYPEDEF || tidx > tt->rows) {
+                       /* "Invalid typedef token %x", type_token */
+                       return FALSE;
+               }
+
+               mono_metadata_decode_row (tt, tidx - 1, cols, MONO_TYPEDEF_SIZE);
+
+               if (class_name)
+                       *class_name = mono_metadata_string_heap (image, cols [MONO_TYPEDEF_NAME]);
+               if (nspace)
+                       *nspace = mono_metadata_string_heap (image, cols [MONO_TYPEDEF_NAMESPACE]);
+               return TRUE;
+       }
+}
+
+
+/**
+ * custom_attr_class_name_from_method_token:
+ * @image: The MonoImage
+ * @method_token: a token for a custom attr constructor in @image
+ * @assembly_token: out argment set to the assembly ref token of the custom attr
+ * @nspace: out argument set to namespace (a string in the string heap of @image) of the custom attr
+ * @class_name: out argument set to the class name of the custom attr.
+ *
+ * Given an @image and a @method_token (which is assumed to be a
+ * constructor), fills in the out arguments with the assembly ref (if
+ * a methodref) and the namespace and class name of the custom
+ * attribute.
+ *
+ * Returns: TRUE on success, FALSE otherwise.
+ *
+ * LOCKING: does not take locks
+ */
+static gboolean
+custom_attr_class_name_from_method_token (MonoImage *image, guint32 method_token, guint32 *assembly_token, const gchar **nspace, const gchar **class_name)
+{
+       /* This only works with method tokens constructed from a
+        * custom attr token, which can only be methoddef or
+        * memberref */
+       g_assert (mono_metadata_token_table (method_token) == MONO_TABLE_METHOD
+                 || mono_metadata_token_table  (method_token) == MONO_TABLE_MEMBERREF);
+
+       if (mono_metadata_token_table (method_token) == MONO_TABLE_MEMBERREF) {
+               /* method_from_memberref () */
+               guint32 cols[6];
+               guint32 nindex, class_index;
+
+               int idx = mono_metadata_token_index (method_token);
+
+               mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], idx-1, cols, 3);
+               nindex = cols [MONO_MEMBERREF_CLASS] >> MONO_MEMBERREF_PARENT_BITS;
+               class_index = cols [MONO_MEMBERREF_CLASS] & MONO_MEMBERREF_PARENT_MASK;
+               if (class_index == MONO_MEMBERREF_PARENT_TYPEREF) {
+                       guint32 type_token = MONO_TOKEN_TYPE_REF | nindex;
+                       /* mono_class_from_typeref_checked () */
+                       {
+                               guint32 cols [MONO_TYPEREF_SIZE];
+                               MonoTableInfo  *t = &image->tables [MONO_TABLE_TYPEREF];
+
+                               mono_metadata_decode_row (t, (type_token&0xffffff)-1, cols, MONO_TYPEREF_SIZE);
+
+                               if (class_name)
+                                       *class_name = mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAME]);
+                               if (nspace)
+                                       *nspace = mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAMESPACE]);
+                               if (assembly_token)
+                                       *assembly_token = cols [MONO_TYPEREF_SCOPE];
+                               return TRUE;
+                       }
+               } else if (class_index == MONO_MEMBERREF_PARENT_METHODDEF) {
+                       guint32 methoddef_token = MONO_TOKEN_METHOD_DEF | nindex;
+                       if (assembly_token)
+                               *assembly_token = 0;
+                       return custom_attr_class_name_from_methoddef (image, methoddef_token, nspace, class_name);
+               } else {
+                       /* Attributes can't be generic, so it won't be
+                        * a typespec, and they're always
+                        * constructors, so it won't be a moduleref */
+                       g_assert_not_reached ();
+               }
+       } else {
+               /* must be MONO_TABLE_METHOD */
+               if (assembly_token)
+                       *assembly_token = 0;
+               return custom_attr_class_name_from_methoddef (image, method_token, nspace, class_name);
+       }
+}
+
+/**
+ * mono_assembly_metadata_foreach_custom_attr:
+ * @assembly: the assembly to iterate over
+ * @func: the function to call for each custom attribute
+ * @user_data: passed to @func
+ *
+ * Calls @func for each custom attribute type on the given assembly until @func returns TRUE.
+ * Everything is done using low-level metadata APIs, so it is safe to use during assembly loading.
+ *
+ */
+void
+mono_assembly_metadata_foreach_custom_attr (MonoAssembly *assembly, MonoAssemblyMetadataCustomAttrIterFunc func, gpointer user_data)
+{
+       MonoImage *image;
+       guint32 mtoken, i;
+       guint32 cols [MONO_CUSTOM_ATTR_SIZE];
+       MonoTableInfo *ca;
+       guint32 idx;
+
+       /*
+        * This might be called during assembly loading, so do everything using the low-level
+        * metadata APIs.
+        */
+
+       image = assembly->image;
+       g_assert (!image_is_dynamic (image));
+       idx = 1; /* there is only one assembly */
+       idx <<= MONO_CUSTOM_ATTR_BITS;
+       idx |= MONO_CUSTOM_ATTR_ASSEMBLY;
+
+       /* Inlined from mono_custom_attrs_from_index_checked () */
+       ca = &image->tables [MONO_TABLE_CUSTOMATTRIBUTE];
+       i = mono_metadata_custom_attrs_from_index (image, idx);
+       if (!i)
+               return;
+       i --;
+       gboolean stop_iterating = FALSE;
+       while (!stop_iterating && i < ca->rows) {
+               if (mono_metadata_decode_row_col (ca, i, MONO_CUSTOM_ATTR_PARENT) != idx)
+                       break;
+               mono_metadata_decode_row (ca, i, cols, MONO_CUSTOM_ATTR_SIZE);
+               i ++;
+               mtoken = cols [MONO_CUSTOM_ATTR_TYPE] >> MONO_CUSTOM_ATTR_TYPE_BITS;
+               switch (cols [MONO_CUSTOM_ATTR_TYPE] & MONO_CUSTOM_ATTR_TYPE_MASK) {
+               case MONO_CUSTOM_ATTR_TYPE_METHODDEF:
+                       mtoken |= MONO_TOKEN_METHOD_DEF;
+                       break;
+               case MONO_CUSTOM_ATTR_TYPE_MEMBERREF:
+                       mtoken |= MONO_TOKEN_MEMBER_REF;
+                       break;
+               default:
+                       g_warning ("Unknown table for custom attr type %08x", cols [MONO_CUSTOM_ATTR_TYPE]);
+                       continue;
+               }
+
+               const char *nspace = NULL;
+               const char *name = NULL;
+               guint32 assembly_token = 0;
+
+               if (!custom_attr_class_name_from_method_token (image, mtoken, &assembly_token, &nspace, &name))
+                       continue;
+
+               stop_iterating = func (image, assembly_token, nspace, name, mtoken, user_data);
+       }
+}
index adb8909f460117ceebfa8be3facd485151765bd6..020b0dd00c4406bc0d482714b2af17e65836b0d6 100644 (file)
@@ -43,6 +43,7 @@
 #include <mono/metadata/w32mutex.h>
 #include <mono/metadata/w32semaphore.h>
 #include <mono/metadata/w32event.h>
+#include <mono/metadata/w32process.h>
 #include <metadata/threads.h>
 #include <metadata/profiler-private.h>
 #include <mono/metadata/coree.h>
@@ -510,7 +511,7 @@ mono_init_internal (const char *filename, const char *exe_filename, const char *
        static MonoDomain *domain = NULL;
        MonoAssembly *ass = NULL;
        MonoImageOpenStatus status = MONO_IMAGE_OK;
-       const MonoRuntimeInfo* runtimes [G_N_ELEMENTS (supported_runtimes) + 1];
+       const MonoRuntimeInfo* runtimes [G_N_ELEMENTS (supported_runtimes) + 1] = { NULL };
        int n, dummy;
 
 #ifdef DEBUG_DOMAIN_UNLOAD
@@ -534,6 +535,7 @@ mono_init_internal (const char *filename, const char *exe_filename, const char *
        mono_w32mutex_init ();
        mono_w32semaphore_init ();
        mono_w32event_init ();
+       mono_w32process_init ();
 
 #ifndef DISABLE_PERFCOUNTERS
        mono_perfcounters_init ();
@@ -814,16 +816,6 @@ mono_init_internal (const char *filename, const char *exe_filename, const char *
 
        mono_profiler_appdomain_name (domain, domain->friendly_name);
 
-       /* Have to do this quite late so that we at least have System.Object */
-       MonoError custom_attr_error;
-       if (mono_assembly_has_reference_assembly_attribute (ass, &custom_attr_error)) {
-               char *corlib_file = g_build_filename (mono_assembly_getrootdir (), "mono", current_runtime->framework_version, "mscorlib.dll", NULL);
-               g_print ("Could not load file or assembly %s. Reference assemblies should not be loaded for execution.  They can only be loaded in the Reflection-only loader context.", corlib_file);
-               g_free (corlib_file);
-               exit (1);
-       }
-       mono_error_assert_ok (&custom_attr_error);
-
        return domain;
 }
 
@@ -908,6 +900,8 @@ mono_cleanup (void)
        mono_native_tls_free (appdomain_thread_id);
        mono_coop_mutex_destroy (&appdomains_mutex);
 
+       mono_w32process_cleanup ();
+
 #ifndef HOST_WIN32
        wapi_cleanup ();
 #endif
index dd722f289a958c6a8c6452a9fc6bb073d7268fe5..7f55a5e9542fb83ebeec0a1d401b2849cc09404e 100644 (file)
@@ -35,7 +35,7 @@
 #include <mono/metadata/marshal.h>
 #include <mono/utils/strenc.h>
 #include <utils/mono-io-portability.h>
-#include <mono/utils/w32handle.h>
+#include <mono/metadata/w32handle.h>
 
 #undef DEBUG
 
index 84e3b4aa68d75000fbec036787887c36f1fe8930..4b9ce74499e04ec81a5b1ad1e422615d7c44636b 100644 (file)
@@ -63,7 +63,9 @@ enum {
        COULD_NOT_OPEN,
        CAPACITY_MUST_BE_POSITIVE,
        INVALID_FILE_MODE,
-       COULD_NOT_MAP_MEMORY
+       COULD_NOT_MAP_MEMORY,
+       ACCESS_DENIED,
+       CAPACITY_LARGER_THAN_LOGICAL_ADDRESS_SPACE
 };
 
 enum {
@@ -300,10 +302,16 @@ static void*
 open_memory_map (const char *c_mapName, int mode, gint64 *capacity, int access, int options, int *ioerror)
 {
        MmapHandle *handle;
-       if (*capacity <= 1) {
+       if (*capacity <= 0) {
                *ioerror = CAPACITY_MUST_BE_POSITIVE;
                return NULL;
        }
+#if SIZEOF_VOID_P == 4
+       if (*capacity > UINT32_MAX) {
+               *ioerror = CAPACITY_LARGER_THAN_LOGICAL_ADDRESS_SPACE;
+               return NULL;
+       }
+#endif
 
        if (!(mode == FILE_MODE_CREATE_NEW || mode == FILE_MODE_OPEN_OR_CREATE || mode == FILE_MODE_OPEN)) {
                *ioerror = INVALID_FILE_MODE;
@@ -499,8 +507,11 @@ mono_mmap_map (void *handle, gint64 offset, gint64 *size, int access, void **mma
        struct stat buf = { 0 };
        fstat (fh->fd, &buf); //FIXME error handling
 
+       *mmap_handle = NULL;
+       *base_address = NULL;
+
        if (offset > buf.st_size || ((eff_size + offset) > buf.st_size && !is_special_zero_size_file (&buf)))
-               goto error;
+               return ACCESS_DENIED;
        /**
          * We use the file size if one of the following conditions is true:
          *  -input size is zero
@@ -522,9 +533,6 @@ mono_mmap_map (void *handle, gint64 offset, gint64 *size, int access, void **mma
                return 0;
        }
 
-error:
-       *mmap_handle = NULL;
-       *base_address = NULL;
        return COULD_NOT_MAP_MEMORY;
 }
 
index dba37472c34741355a3f5e1e954f4c54a86801ad..b0fd5d9b8962bbfbcfefa532774b6fdb94adf6dd 100644 (file)
 /*
- * file-mmap-posix.c: File mmap internal calls
+ * file-mmap-windows.c: MemoryMappedFile internal calls for Windows
  *
- * Author:
- *     Rodrigo Kumpera
- *
- * Copyright 2014 Xamarin Inc (http://www.xamarin.com)
+ * Copyright 2016 Microsoft
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
+/*
+ * The code in this file has been inspired by the CoreFX MemoryMappedFile Windows implementation contained in the files
+ *
+ * https://github.com/dotnet/corefx/blob/master/src/System.IO.MemoryMappedFiles/src/System/IO/MemoryMappedFiles/MemoryMappedFile.Windows.cs
+ * https://github.com/dotnet/corefx/blob/master/src/System.IO.MemoryMappedFiles/src/System/IO/MemoryMappedFiles/MemoryMappedView.Windows.cs
+ */
+
 #include <config.h>
 
 #ifdef HOST_WIN32
 
 #include <glib.h>
-#include <string.h>
-#include <errno.h>
-
 
-#include <mono/metadata/object.h>
 #include <mono/metadata/file-mmap.h>
 
-void *
-mono_mmap_open_file (MonoString *path, int mode, MonoString *mapName, gint64 *capacity, int access, int options, int *error)
+// These control the retry behaviour when lock violation errors occur during Flush:
+#define MAX_FLUSH_WAITS 15  // must be <=30
+#define MAX_FLUSH_RETIRES_PER_WAIT 20
+
+typedef struct {
+       void *address;
+       size_t length;
+} MmapInstance;
+
+enum {
+       BAD_CAPACITY_FOR_FILE_BACKED = 1,
+       CAPACITY_SMALLER_THAN_FILE_SIZE,
+       FILE_NOT_FOUND,
+       FILE_ALREADY_EXISTS,
+       PATH_TOO_LONG,
+       COULD_NOT_OPEN,
+       CAPACITY_MUST_BE_POSITIVE,
+       INVALID_FILE_MODE,
+       COULD_NOT_MAP_MEMORY,
+       ACCESS_DENIED,
+       CAPACITY_LARGER_THAN_LOGICAL_ADDRESS_SPACE
+};
+
+enum {
+       FILE_MODE_CREATE_NEW = 1,
+       FILE_MODE_CREATE = 2,
+       FILE_MODE_OPEN = 3,
+       FILE_MODE_OPEN_OR_CREATE = 4,
+       FILE_MODE_TRUNCATE = 5,
+       FILE_MODE_APPEND = 6,
+};
+
+enum {
+       MMAP_FILE_ACCESS_READ_WRITE = 0,
+       MMAP_FILE_ACCESS_READ = 1,
+       MMAP_FILE_ACCESS_WRITE = 2,
+       MMAP_FILE_ACCESS_COPY_ON_WRITE = 3,
+       MMAP_FILE_ACCESS_READ_EXECUTE = 4,
+       MMAP_FILE_ACCESS_READ_WRITE_EXECUTE = 5,
+};
+
+static DWORD get_page_access (int access)
 {
-       g_error ("No windows backend");
-       return NULL;
+       switch (access) {
+       case MMAP_FILE_ACCESS_READ:
+               return PAGE_READONLY;
+       case MMAP_FILE_ACCESS_READ_WRITE:
+               return PAGE_READWRITE;
+       case MMAP_FILE_ACCESS_COPY_ON_WRITE:
+               return PAGE_WRITECOPY;
+       case MMAP_FILE_ACCESS_READ_EXECUTE:
+               return PAGE_EXECUTE_READ;
+       case MMAP_FILE_ACCESS_READ_WRITE_EXECUTE:
+               return PAGE_EXECUTE_READWRITE;
+       default:
+               g_error ("unknown MemoryMappedFileAccess %d", access);
+       }
 }
 
-void *
-mono_mmap_open_handle (void *handle, MonoString *mapName, gint64 *capacity, int access, int options, int *error)
+static DWORD get_file_access (int access)
 {
-       g_error ("No windows backend");
-       return NULL;
+       switch (access) {
+       case MMAP_FILE_ACCESS_READ:
+       case MMAP_FILE_ACCESS_READ_EXECUTE:
+               return GENERIC_READ;
+       case MMAP_FILE_ACCESS_READ_WRITE:
+       case MMAP_FILE_ACCESS_COPY_ON_WRITE:
+       case MMAP_FILE_ACCESS_READ_WRITE_EXECUTE:
+               return GENERIC_READ | GENERIC_WRITE;
+       case MMAP_FILE_ACCESS_WRITE:
+               return GENERIC_WRITE;
+       default:
+               g_error ("unknown MemoryMappedFileAccess %d", access);
+       }
 }
 
-void
-mono_mmap_close (void *mmap_handle)
+static int get_file_map_access (int access)
 {
-       g_error ("No windows backend");
+       switch (access) {
+       case MMAP_FILE_ACCESS_READ:
+               return FILE_MAP_READ;
+       case MMAP_FILE_ACCESS_WRITE:
+               return FILE_MAP_WRITE;
+       case MMAP_FILE_ACCESS_READ_WRITE:
+               return FILE_MAP_READ | FILE_MAP_WRITE;
+       case MMAP_FILE_ACCESS_COPY_ON_WRITE:
+               return FILE_MAP_COPY;
+       case MMAP_FILE_ACCESS_READ_EXECUTE:
+               return FILE_MAP_EXECUTE | FILE_MAP_READ;
+       case MMAP_FILE_ACCESS_READ_WRITE_EXECUTE:
+               return FILE_MAP_EXECUTE | FILE_MAP_READ | FILE_MAP_WRITE;
+       default:
+               g_error ("unknown MemoryMappedFileAccess %d", access);
+       }
 }
 
-void
-mono_mmap_configure_inheritability (void *mmap_handle, gboolean inheritability)
+static int convert_win32_error (int error, int def)
 {
-       g_error ("No windows backend");
+       switch (error) {
+       case ERROR_FILE_NOT_FOUND:
+               return FILE_NOT_FOUND;
+       case ERROR_FILE_EXISTS:
+       case ERROR_ALREADY_EXISTS:
+               return FILE_ALREADY_EXISTS;
+       case ERROR_ACCESS_DENIED:
+               return ACCESS_DENIED;
+       }
+       return def;
 }
 
-void
-mono_mmap_flush (void *mmap_handle)
+static void *open_handle (void *handle, MonoString *mapName, int mode, gint64 *capacity, int access, int options, int *error)
 {
-       g_error ("No windows backend");
+       g_assert (handle != NULL);
+
+       wchar_t *w_mapName = NULL;
+       HANDLE result = NULL;
+
+       if (handle == INVALID_HANDLE_VALUE) {
+               if (*capacity <= 0) {
+                       *error = CAPACITY_MUST_BE_POSITIVE;
+                       return NULL;
+               }
+#if SIZEOF_VOID_P == 4
+               if (*capacity > UINT32_MAX) {
+                       *error = CAPACITY_LARGER_THAN_LOGICAL_ADDRESS_SPACE;
+                       return NULL;
+               }
+#endif
+               if (!(mode == FILE_MODE_CREATE_NEW || mode == FILE_MODE_OPEN_OR_CREATE || mode == FILE_MODE_OPEN)) {
+                       *error = INVALID_FILE_MODE;
+                       return NULL;
+               }
+       } else {
+               FILE_STANDARD_INFO info;
+               if (!GetFileInformationByHandleEx ((HANDLE) handle, FileStandardInfo, &info, sizeof (FILE_STANDARD_INFO))) {
+                       *error = convert_win32_error (GetLastError (), COULD_NOT_OPEN);
+                       return NULL;
+               }
+               if (*capacity == 0) {
+                       if (info.EndOfFile.QuadPart == 0) {
+                               *error = CAPACITY_SMALLER_THAN_FILE_SIZE;
+                               return NULL;
+                       }
+               } else if (*capacity < info.EndOfFile.QuadPart) {
+                       *error = CAPACITY_SMALLER_THAN_FILE_SIZE;
+                       return NULL;
+               }
+       }
+
+       w_mapName = mapName ? mono_string_to_utf16 (mapName) : NULL;
+
+       if (mode == FILE_MODE_CREATE_NEW || handle != INVALID_HANDLE_VALUE) {
+               result = CreateFileMappingW ((HANDLE)handle, NULL, get_page_access (access) | options, (DWORD)(((guint64)*capacity) >> 32), (DWORD)*capacity, w_mapName);
+               if (result && GetLastError () == ERROR_ALREADY_EXISTS) {
+                       CloseHandle (result);
+                       result = NULL;
+                       *error = FILE_ALREADY_EXISTS;
+               } else if (!result && GetLastError () != NO_ERROR) {
+                       *error = convert_win32_error (GetLastError (), COULD_NOT_OPEN);
+               }
+       } else if (mode == FILE_MODE_OPEN || mode == FILE_MODE_OPEN_OR_CREATE && access == MMAP_FILE_ACCESS_WRITE) {
+               result = OpenFileMappingW (get_file_map_access (access), FALSE, w_mapName);
+               if (!result) {
+                       if (mode == FILE_MODE_OPEN_OR_CREATE && GetLastError () == ERROR_FILE_NOT_FOUND) {
+                               *error = INVALID_FILE_MODE;
+                       } else {
+                               *error = convert_win32_error (GetLastError (), COULD_NOT_OPEN);
+                       }
+               }
+       } else if (mode == FILE_MODE_OPEN_OR_CREATE) {
+
+               // This replicates how CoreFX does MemoryMappedFile.CreateOrOpen ().
+
+               /// Try to open the file if it exists -- this requires a bit more work. Loop until we can
+               /// either create or open a memory mapped file up to a timeout. CreateFileMapping may fail
+               /// if the file exists and we have non-null security attributes, in which case we need to
+               /// use OpenFileMapping.  But, there exists a race condition because the memory mapped file
+               /// may have closed between the two calls -- hence the loop. 
+               /// 
+               /// The retry/timeout logic increases the wait time each pass through the loop and times 
+               /// out in approximately 1.4 minutes. If after retrying, a MMF handle still hasn't been opened, 
+               /// throw an InvalidOperationException.
+
+               guint32 waitRetries = 14;   //((2^13)-1)*10ms == approximately 1.4mins
+               guint32 waitSleep = 0;
+
+               while (waitRetries > 0) {
+                       result = CreateFileMappingW ((HANDLE)handle, NULL, get_page_access (access) | options, (DWORD)(((guint64)*capacity) >> 32), (DWORD)*capacity, w_mapName);
+                       if (result)
+                               break;
+                       if (GetLastError() != ERROR_ACCESS_DENIED) {
+                               *error = convert_win32_error (GetLastError (), COULD_NOT_OPEN);
+                               break;
+                       }
+                       result = OpenFileMappingW (get_file_map_access (access), FALSE, w_mapName);
+                       if (result)
+                               break;
+                       if (GetLastError () != ERROR_FILE_NOT_FOUND) {
+                               *error = convert_win32_error (GetLastError (), COULD_NOT_OPEN);
+                               break;
+                       }
+                       // increase wait time
+                       --waitRetries;
+                       if (waitSleep == 0) {
+                               waitSleep = 10;
+                       } else {
+                               mono_thread_info_sleep (waitSleep, NULL);
+                               waitSleep *= 2;
+                       }
+               }
+
+               if (!result) {
+                       *error = COULD_NOT_OPEN;
+               }
+       }
+
+       if (w_mapName)
+               g_free (w_mapName);
+       return result;
 }
 
+void *mono_mmap_open_file (MonoString *path, int mode, MonoString *mapName, gint64 *capacity, int access, int options, int *error)
+{
+       g_assert (path != NULL || mapName != NULL);
+
+       wchar_t *w_path = NULL;
+       HANDLE hFile = INVALID_HANDLE_VALUE;
+       HANDLE result = NULL;
+       gboolean delete_on_error = FALSE;
 
+       if (path) {
+               w_path = mono_string_to_utf16 (path);
+               WIN32_FILE_ATTRIBUTE_DATA file_attrs;
+               gboolean existed = GetFileAttributesExW (w_path, GetFileExInfoStandard, &file_attrs);
+               if (!existed && mode == FILE_MODE_CREATE_NEW && *capacity == 0) {
+                       *error = CAPACITY_SMALLER_THAN_FILE_SIZE;
+                       goto done;
+               }
+               hFile = CreateFileW (w_path, get_file_access (access), FILE_SHARE_READ, NULL, mode, FILE_ATTRIBUTE_NORMAL, NULL);
+               if (hFile == INVALID_HANDLE_VALUE) {
+                       *error = convert_win32_error (GetLastError (), COULD_NOT_OPEN);
+                       goto done;
+               }
+               delete_on_error = !existed;
+       }
 
-int
-mono_mmap_map (void *handle, gint64 offset, gint64 *size, int access, void **mmap_handle, void **base_address)
+       result = open_handle (hFile, mapName, mode, capacity, access, options, error);
+
+done:
+       if (!result && delete_on_error)
+               DeleteFileW (w_path);
+       if (w_path)
+               g_free (w_path);
+
+       return result;
+}
+
+void *mono_mmap_open_handle (void *handle, MonoString *mapName, gint64 *capacity, int access, int options, int *error)
 {
-       g_error ("No windows backend");
+       g_assert (handle != NULL);
+
+       return open_handle (handle, mapName, FILE_MODE_OPEN, capacity, access, options, error);
+}
+
+void mono_mmap_close (void *mmap_handle)
+{
+       g_assert (mmap_handle);
+       CloseHandle ((HANDLE) mmap_handle);
+}
+
+void mono_mmap_configure_inheritability (void *mmap_handle, gboolean inheritability)
+{
+       g_assert (mmap_handle);
+       if (!SetHandleInformation ((HANDLE) mmap_handle, HANDLE_FLAG_INHERIT, inheritability ? HANDLE_FLAG_INHERIT : 0)) {
+               g_error ("mono_mmap_configure_inheritability: SetHandleInformation failed with error %d!", GetLastError ());
+       }
+}
+
+void mono_mmap_flush (void *mmap_handle)
+{
+       g_assert (mmap_handle);
+       MmapInstance *h = (MmapInstance *)mmap_handle;
+
+       if (FlushViewOfFile (h->address, h->length))
+               return;
+
+       // This replicates how CoreFX does MemoryMappedView.Flush ().
+
+       // It is a known issue within the NTFS transaction log system that
+       // causes FlushViewOfFile to intermittently fail with ERROR_LOCK_VIOLATION
+       // As a workaround, we catch this particular error and retry the flush operation 
+       // a few milliseconds later. If it does not work, we give it a few more tries with
+       // increasing intervals. Eventually, however, we need to give up. In ad-hoc tests
+       // this strategy successfully flushed the view after no more than 3 retries.
+
+       if (GetLastError () != ERROR_LOCK_VIOLATION)
+               // TODO: Propagate error to caller
+               return;
+
+       for (int w = 0; w < MAX_FLUSH_WAITS; w++) {
+               int pause = (1 << w);  // MaxFlushRetries should never be over 30
+               mono_thread_info_sleep (pause, NULL);
+
+               for (int r = 0; r < MAX_FLUSH_RETIRES_PER_WAIT; r++) {
+                       if (FlushViewOfFile (h->address, h->length))
+                               return;
+
+                       if (GetLastError () != ERROR_LOCK_VIOLATION)
+                               // TODO: Propagate error to caller
+                               return;
+
+                       mono_thread_info_yield ();
+               }
+       }
+
+       // We got to here, so there was no success:
+       // TODO: Propagate error to caller
+}
+
+int mono_mmap_map (void *handle, gint64 offset, gint64 *size, int access, void **mmap_handle, void **base_address)
+{
+       static DWORD allocationGranularity = 0;
+       if (allocationGranularity == 0) {
+               SYSTEM_INFO info;
+               GetSystemInfo (&info);
+               allocationGranularity = info.dwAllocationGranularity;
+       }
+
+       gint64 extraMemNeeded = offset % allocationGranularity;
+       guint64 newOffset = offset - extraMemNeeded;
+       gint64 nativeSize = (*size != 0) ? *size + extraMemNeeded : 0;
+
+#if SIZEOF_VOID_P == 4
+       if (nativeSize > UINT32_MAX)
+               return CAPACITY_LARGER_THAN_LOGICAL_ADDRESS_SPACE;
+#endif
+       
+       void *address = MapViewOfFile ((HANDLE) handle, get_file_map_access (access), (DWORD) (newOffset >> 32), (DWORD) newOffset, (SIZE_T) nativeSize);
+       if (!address)
+               return convert_win32_error (GetLastError (), COULD_NOT_MAP_MEMORY);
+
+       // Query the view for its size and allocation type
+       MEMORY_BASIC_INFORMATION viewInfo;
+       VirtualQuery (address, &viewInfo, sizeof (MEMORY_BASIC_INFORMATION));
+       guint64 viewSize = (guint64) viewInfo.RegionSize;
+
+       // Allocate the pages if we were using the MemoryMappedFileOptions.DelayAllocatePages option
+       // OR check if the allocated view size is smaller than the expected native size
+       // If multiple overlapping views are created over the file mapping object, the pages in a given region
+       // could have different attributes(MEM_RESERVE OR MEM_COMMIT) as MapViewOfFile preserves coherence between 
+       // views created on a mapping object backed by same file.
+       // In which case, the viewSize will be smaller than nativeSize required and viewState could be MEM_COMMIT 
+       // but more pages may need to be committed in the region.
+       // This is because, VirtualQuery function(that internally invokes VirtualQueryEx function) returns the attributes 
+       // and size of the region of pages with matching attributes starting from base address.
+       // VirtualQueryEx: http://msdn.microsoft.com/en-us/library/windows/desktop/aa366907(v=vs.85).aspx
+       if (((viewInfo.State & MEM_RESERVE) != 0) || viewSize < (guint64) nativeSize) {
+               void *tempAddress = VirtualAlloc (address, nativeSize != 0 ? nativeSize : viewSize, MEM_COMMIT, get_page_access (access));
+               if (!tempAddress) {
+                       return convert_win32_error (GetLastError (), COULD_NOT_MAP_MEMORY);
+               }
+               // again query the view for its new size
+               VirtualQuery (address, &viewInfo, sizeof (MEMORY_BASIC_INFORMATION));
+               viewSize = (guint64) viewInfo.RegionSize;
+       }
+
+       if (*size == 0)
+               *size = viewSize - extraMemNeeded;
+
+       MmapInstance *h = g_malloc0 (sizeof (MmapInstance));
+       h->address = address;
+       h->length = *size + extraMemNeeded;
+       *mmap_handle = h;
+       *base_address = (char*) address + (offset - newOffset);
+
        return 0;
 }
 
-gboolean
-mono_mmap_unmap (void *mmap_handle)
+gboolean mono_mmap_unmap (void *mmap_handle)
 {
-       g_error ("No windows backend");
-       return TRUE;
+       g_assert (mmap_handle);
+
+       MmapInstance *h = (MmapInstance *) mmap_handle;
+
+       gboolean result = UnmapViewOfFile (h->address);
+
+       g_free (h);
+       return result;
 }
 
 #endif
index afb6522d1cba060c2c664bc069377fcc0aa1b621..2ef55c6e6733baa729f9a37c2bbb544d82c7d03d 100644 (file)
@@ -360,6 +360,8 @@ guint mono_gc_get_vtable_bits (MonoClass *klass);
 
 void mono_gc_register_altstack (gpointer stack, gint32 stack_size, gpointer altstack, gint32 altstack_size);
 
+gboolean mono_gc_is_critical_method (MonoMethod *method);
+
 /* If set, print debugging messages around finalizers. */
 extern gboolean log_finalizers;
 
index ae4329be666865957ba53ad41f60586c4c2cc065..e66b4da35a2b97c6ae48945d7f18dc5325ee0fc3 100644 (file)
@@ -91,13 +91,13 @@ static void mono_reference_queue_cleanup (void);
 static void reference_queue_clear_for_domain (MonoDomain *domain);
 
 
-static guint32
-guarded_wait (HANDLE handle, guint32 timeout, gboolean alertable)
+static MonoThreadInfoWaitRet
+guarded_wait (MonoThreadHandle *thread_handle, guint32 timeout, gboolean alertable)
 {
-       guint32 result;
+       MonoThreadInfoWaitRet result;
 
        MONO_ENTER_GC_SAFE;
-       result = WaitForSingleObjectEx (handle, timeout, alertable);
+       result = mono_thread_info_wait_one_handle (thread_handle, timeout, alertable);
        MONO_EXIT_GC_SAFE;
 
        return result;
@@ -642,7 +642,9 @@ ves_icall_System_GC_WaitForPendingFinalizers (void)
        ResetEvent (pending_done_event);
        mono_gc_finalize_notify ();
        /* g_print ("Waiting for pending finalizers....\n"); */
-       guarded_wait (pending_done_event, INFINITE, TRUE);
+       MONO_ENTER_GC_SAFE;
+       WaitForSingleObjectEx (pending_done_event, INFINITE, TRUE);
+       MONO_EXIT_GC_SAFE;
        /* g_print ("Done pending....\n"); */
 #else
        gboolean alerted = FALSE;
@@ -730,7 +732,7 @@ ves_icall_System_GCHandle_GetAddrOfPinnedObject (guint32 handle)
                } else {
                        /* the C# code will check and throw the exception */
                        /* FIXME: missing !klass->blittable test, see bug #61134 */
-                       if ((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT)
+                       if (mono_class_is_auto_layout (klass))
                                return (gpointer)-1;
                        return (char*)obj + sizeof (MonoObject);
                }
@@ -1014,6 +1016,7 @@ mono_gc_cleanup (void)
        if (!gc_disabled) {
                finished = TRUE;
                if (mono_thread_internal_current () != gc_thread) {
+                       int ret;
                        gint64 start_ticks = mono_msec_ticks ();
                        gint64 end_ticks = start_ticks + 2000;
 
@@ -1035,8 +1038,6 @@ mono_gc_cleanup (void)
                        }
 
                        if (!finalizer_thread_exited) {
-                               int ret;
-
                                /* Set a flag which the finalizer thread can check */
                                suspend_finalizers = TRUE;
                                mono_gc_suspend_finalizers ();
@@ -1047,23 +1048,22 @@ mono_gc_cleanup (void)
                                /* Wait for it to stop */
                                ret = guarded_wait (gc_thread->handle, 100, TRUE);
 
-                               if (ret == WAIT_TIMEOUT) {
+                               if (ret == MONO_THREAD_INFO_WAIT_RET_TIMEOUT) {
                                        /*
                                         * The finalizer thread refused to exit. Make it stop.
                                         */
                                        mono_thread_internal_stop (gc_thread);
                                        ret = guarded_wait (gc_thread->handle, 100, TRUE);
-                                       g_assert (ret != WAIT_TIMEOUT);
+                                       g_assert (ret != MONO_THREAD_INFO_WAIT_RET_TIMEOUT);
                                        /* The thread can't set this flag */
                                        finalizer_thread_exited = TRUE;
                                }
                        }
 
-                       int ret;
 
                        /* Wait for the thread to actually exit */
                        ret = guarded_wait (gc_thread->handle, INFINITE, TRUE);
-                       g_assert (ret == WAIT_OBJECT_0);
+                       g_assert (ret == MONO_THREAD_INFO_WAIT_RET_SUCCESS_0);
 
                        mono_thread_join (GUINT_TO_POINTER (gc_thread->tid));
                        g_assert (finalizer_thread_exited);
index 44327aed131a7f85595486d2465e19293180d58f..e201b38c687582f3c20bcb50b3d420b58bbddd67 100644 (file)
@@ -163,8 +163,10 @@ mono_handle_stack_scan (HandleStack *stack, GcScanFunc func, gpointer gc_data)
 
        while (cur) {
                int i;
-               for (i = 0; i < cur->size; ++i)
-                       func ((gpointer*)&cur->objects [i], gc_data);
+               for (i = 0; i < cur->size; ++i) {
+                       if (cur->objects [i] != NULL)
+                               func ((gpointer*)&cur->objects [i], gc_data);
+               }
                if (cur == last)
                        break;
                cur = cur->next;
@@ -185,7 +187,7 @@ mono_stack_mark_record_size (MonoThreadInfo *info, HandleStackMark *stackmark, c
        }
 
        if (size > THIS_IS_AN_OK_NUMBER_OF_HANDLES)
-               printf ("%s USED %d handles\n", func_name, size);
+               g_warning ("%s USED %d handles\n", func_name, size);
 }
 
 /*
index d74def55570e8aa4664a99d88058b8dae4fe0b65..f264c4851ac7836012af8b232aae3faf33ddb63c 100644 (file)
@@ -702,9 +702,7 @@ ICALL(MARSHAL_13, "Prelink", ves_icall_System_Runtime_InteropServices_Marshal_Pr
 ICALL(MARSHAL_14, "PrelinkAll", ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll)
 ICALL(MARSHAL_15, "PtrToStringAnsi(intptr)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi)
 ICALL(MARSHAL_16, "PtrToStringAnsi(intptr,int)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi_len)
-#ifndef DISABLE_COM
 ICALL(MARSHAL_17, "PtrToStringBSTR", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringBSTR)
-#endif
 ICALL(MARSHAL_18, "PtrToStringUni(intptr)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringUni)
 ICALL(MARSHAL_19, "PtrToStringUni(intptr,int)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringUni_len)
 ICALL(MARSHAL_20, "PtrToStructure(intptr,System.Type)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStructure_type)
index e2ec7762a3fbd8a2b23a6b227534f6e80b0723d9..45a922c9c78a58492473fcee6ea6742accc7a35a 100644 (file)
@@ -49,9 +49,6 @@ mono_icall_broadcast_setting_change (void);
 void
 mono_icall_write_windows_debug_string (MonoString *message);
 
-MonoBoolean
-mono_icall_close_process (gpointer handle);
-
 gint32
 mono_icall_wait_for_input_idle (gpointer handle, gint32 milliseconds);
 #endif  /* HOST_WIN32 */
@@ -65,18 +62,6 @@ mono_icall_get_logical_drives (void);
 
 guint32
 mono_icall_drive_info_get_drive_type (MonoString *root_path_name);
-
-MonoBoolean
-mono_icall_get_process_working_set_size (gpointer handle, gsize *min, gsize *max);
-
-MonoBoolean
-mono_icall_set_process_working_set_size (gpointer handle, gsize min, gsize max);
-
-gint32
-mono_icall_get_priority_class (gpointer handle);
-
-MonoBoolean
-mono_icall_set_priority_class (gpointer handle, gint32 priorityClass);
 #endif  /* !G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
 
 #endif /* __MONO_METADATA_ICALL_INTERNALS_H__ */
index f27319863c34cd78dd3dcea12af8f3986cfc7d97..0b5afa2624bbf1b11bf6898ff4922bf55b909896 100644 (file)
@@ -85,70 +85,6 @@ mono_icall_wait_for_input_idle (gpointer handle, gint32 milliseconds)
        return WAIT_TIMEOUT;
 }
 
-MonoBoolean
-mono_icall_get_process_working_set_size (gpointer handle, gsize *min, gsize *max)
-{
-       MonoError mono_error;
-       mono_error_init (&mono_error);
-
-       g_unsupported_api ("GetProcessWorkingSetSize");
-
-       mono_error_set_not_supported(&mono_error, G_UNSUPPORTED_API, "GetProcessWorkingSetSize");
-       mono_error_set_pending_exception (&mono_error);
-
-       SetLastError (ERROR_NOT_SUPPORTED);
-
-       return FALSE;
-}
-
-MonoBoolean
-mono_icall_set_process_working_set_size (gpointer handle, gsize min, gsize max)
-{
-       MonoError mono_error;
-       mono_error_init (&mono_error);
-
-       g_unsupported_api ("SetProcessWorkingSetSize");
-
-       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "SetProcessWorkingSetSize");
-       mono_error_set_pending_exception (&mono_error);
-
-       SetLastError (ERROR_NOT_SUPPORTED);
-
-       return FALSE;
-}
-
-gint32
-mono_icall_get_priority_class (gpointer handle)
-{
-       MonoError mono_error;
-       mono_error_init (&mono_error);
-
-       g_unsupported_api ("GetPriorityClass");
-
-       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "GetPriorityClass");
-       mono_error_set_pending_exception (&mono_error);
-
-       SetLastError (ERROR_NOT_SUPPORTED);
-
-       return FALSE;
-}
-
-MonoBoolean
-mono_icall_set_priority_class (gpointer handle, gint32 priorityClass)
-{
-       MonoError mono_error;
-       mono_error_init (&mono_error);
-
-       g_unsupported_api ("SetPriorityClass");
-
-       mono_error_set_not_supported(&mono_error, G_UNSUPPORTED_API, "SetPriorityClass");
-       mono_error_set_pending_exception (&mono_error);
-
-       SetLastError (ERROR_NOT_SUPPORTED);
-
-       return FALSE;
-}
-
 #else /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
 
 #ifdef _MSC_VER
index cd72e481eb4850f5bbe231644a4e1b5c2ea0b022..9ebcf30f31b5f2f2bbb85b1e1515f08d255b8b54 100644 (file)
@@ -213,9 +213,4 @@ mono_icall_write_windows_debug_string (MonoString *message)
        OutputDebugString (mono_string_chars (message));
 }
 
-MonoBoolean
-mono_icall_close_process (gpointer handle)
-{
-       return (MonoBoolean)(CloseHandle (handle));
-}
 #endif /* HOST_WIN32 */
index ce2ea4883c663edeed6bdf9400cdc0f4122614bc..0f54ea16dc0211be3e891e3d9e1a30d0e57cd9c1 100644 (file)
@@ -63,7 +63,7 @@
 #include <mono/metadata/sysmath.h>
 #include <mono/metadata/string-icalls.h>
 #include <mono/metadata/debug-helpers.h>
-#include <mono/metadata/process.h>
+#include <mono/metadata/w32process.h>
 #include <mono/metadata/environment.h>
 #include <mono/metadata/profiler-private.h>
 #include <mono/metadata/locales.h>
@@ -944,7 +944,7 @@ ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (Mo
        klass = mono_class_from_mono_type (handle);
        MONO_CHECK_ARG (handle, klass,);
 
-       if (klass->generic_container)
+       if (mono_class_is_gtd (klass))
                return;
 
        vtable = mono_class_vtable_full (mono_domain_get (), klass, &error);
@@ -1302,7 +1302,7 @@ get_caller_no_system_or_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboole
 }
 
 static MonoReflectionType *
-type_from_parsed_name (MonoTypeNameParse *info, MonoBoolean ignoreCase, MonoError *error)
+type_from_parsed_name (MonoTypeNameParse *info, MonoBoolean ignoreCase, MonoAssembly **caller_assembly, MonoError *error)
 {
        MonoMethod *m, *dest;
 
@@ -1353,6 +1353,7 @@ type_from_parsed_name (MonoTypeNameParse *info, MonoBoolean ignoreCase, MonoErro
        } else {
                g_warning (G_STRLOC);
        }
+       *caller_assembly = assembly;
 
        if (info->assembly.name)
                assembly = mono_assembly_load (&info->assembly, assembly ? assembly->basedir : NULL, NULL);
@@ -1397,6 +1398,7 @@ ves_icall_System_Type_internal_from_name (MonoString *name,
        MonoTypeNameParse info;
        MonoReflectionType *type = NULL;
        gboolean parsedOk;
+       MonoAssembly *caller_assembly;
 
        char *str = mono_string_to_utf8_checked (name, &error);
        if (!is_ok (&error))
@@ -1412,18 +1414,27 @@ ves_icall_System_Type_internal_from_name (MonoString *name,
                goto leave;
        }
 
-       type = type_from_parsed_name (&info, ignoreCase, &error);
+       type = type_from_parsed_name (&info, ignoreCase, &caller_assembly, &error);
 
-       mono_reflection_free_type_info (&info);
-
-       if (!is_ok (&error))
+       if (!is_ok (&error)) {
+               mono_reflection_free_type_info (&info);
                goto leave;
+       }
 
-       if (type == NULL){
+       if (type == NULL) {
                if (throwOnError) {
-                       mono_error_set_type_load_name (&error, g_strdup (str), g_strdup (""), "");
-                       goto leave;
+                       char *tname = info.name_space ? g_strdup_printf ("%s.%s", info.name_space, info.name) : g_strdup (info.name);
+                       char *aname;
+                       if (info.assembly.name)
+                               aname = mono_stringify_assembly_name (&info.assembly);
+                       else if (caller_assembly)
+                               aname = mono_stringify_assembly_name (mono_assembly_get_name (caller_assembly));
+                       else
+                               aname = g_strdup ("");
+                       mono_error_set_type_load_name (&error, tname, aname, "");
                }
+               mono_reflection_free_type_info (&info);
+               goto leave;
        }
        
 leave:
@@ -1659,7 +1670,7 @@ ICALL_EXPORT guint32
 ves_icall_RuntimeTypeHandle_GetAttributes (MonoReflectionType *type)
 {
        MonoClass *klass = mono_class_from_mono_type (type->type);
-       return klass->flags;
+       return mono_class_get_flags (klass);
 }
 
 ICALL_EXPORT MonoReflectionMarshalAsAttribute*
@@ -1671,8 +1682,9 @@ ves_icall_System_Reflection_FieldInfo_get_marshal_info (MonoReflectionField *fie
        MonoType *ftype;
        int i;
 
-       if (klass->generic_container ||
-           (klass->generic_class && klass->generic_class->context.class_inst->is_open))
+       MonoGenericClass *gklass = mono_class_try_get_generic_class (klass);
+       if (mono_class_is_gtd (klass) ||
+           (gklass && gklass->context.class_inst->is_open))
                return NULL;
 
        ftype = mono_field_get_type (field->field);
@@ -1882,8 +1894,6 @@ ICALL_EXPORT gint32
 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
 {
        MonoClass *parent = field->field->parent;
-       if (!parent->size_inited)
-               mono_class_init (parent);
        mono_class_setup_fields (parent);
 
        return field->field->offset - sizeof (MonoObject);
@@ -2360,7 +2370,7 @@ fill_iface_array (gpointer key, gpointer value, gpointer user_data)
        if (!mono_error_ok (data->error))
                return;
 
-       if (data->context && ic->generic_class && ic->generic_class->context.class_inst->is_open) {
+       if (data->context && mono_class_is_ginst (ic) && mono_class_get_generic_class (ic)->context.class_inst->is_open) {
                inflated = ret = mono_class_inflate_generic_type_checked (ret, data->context, data->error);
                if (!mono_error_ok (data->error))
                        return;
@@ -2395,9 +2405,9 @@ ves_icall_RuntimeType_GetInterfaces (MonoReflectionType* type)
 
        GHashTable *iface_hash = g_hash_table_new (get_interfaces_hash, NULL);
 
-       if (klass->generic_class && klass->generic_class->context.class_inst->is_open) {
+       if (mono_class_is_ginst (klass) && mono_class_get_generic_class (klass)->context.class_inst->is_open) {
                data.context = mono_class_get_context (klass);
-               klass = klass->generic_class->container_class;
+               klass = mono_class_get_generic_class (klass)->container_class;
        }
 
        for (parent = klass; parent; parent = parent->parent) {
@@ -2720,8 +2730,8 @@ ves_icall_RuntimeType_GetGenericArguments (MonoReflectionType *type, MonoBoolean
 
        klass = mono_class_from_mono_type (type->type);
 
-       if (klass->generic_container) {
-               MonoGenericContainer *container = klass->generic_container;
+       if (mono_class_is_gtd (klass)) {
+               MonoGenericContainer *container = mono_class_get_generic_container (klass);
                res = create_type_array (domain, runtimeTypeArray, container->type_argc, &error);
                if (mono_error_set_pending_exception (&error))
                        return NULL;
@@ -2734,8 +2744,8 @@ ves_icall_RuntimeType_GetGenericArguments (MonoReflectionType *type, MonoBoolean
 
                        mono_array_setref (res, i, rt);
                }
-       } else if (klass->generic_class) {
-               MonoGenericInst *inst = klass->generic_class->context.class_inst;
+       } else if (mono_class_is_ginst (klass)) {
+               MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
                res = create_type_array (domain, runtimeTypeArray, inst->type_argc, &error);
                if (mono_error_set_pending_exception (&error))
                        return NULL;
@@ -2764,7 +2774,7 @@ ves_icall_RuntimeTypeHandle_IsGenericTypeDefinition (MonoReflectionType *type)
                return FALSE;
 
        klass = mono_class_from_mono_type (type->type);
-       return klass->generic_container != NULL;
+       return mono_class_is_gtd (klass);
 }
 
 ICALL_EXPORT MonoReflectionType*
@@ -2779,11 +2789,11 @@ ves_icall_RuntimeTypeHandle_GetGenericTypeDefinition_impl (MonoReflectionType *t
 
        klass = mono_class_from_mono_type (type->type);
 
-       if (klass->generic_container) {
+       if (mono_class_is_gtd (klass)) {
                return type; /* check this one */
        }
-       if (klass->generic_class) {
-               MonoClass *generic_class = klass->generic_class->container_class;
+       if (mono_class_is_ginst (klass)) {
+               MonoClass *generic_class = mono_class_get_generic_class (klass)->container_class;
                gpointer tb;
 
                tb = mono_class_get_ref_info (generic_class);
@@ -2832,7 +2842,7 @@ ves_icall_RuntimeType_MakeGenericType (MonoReflectionType *type, MonoArray *type
        klass = mono_class_from_mono_type (geninst);
 
        /*we might inflate to the GTD*/
-       if (klass->generic_class && !mono_verifier_class_is_valid_generic_instantiation (klass)) {
+       if (mono_class_is_ginst (klass) && !mono_verifier_class_is_valid_generic_instantiation (klass)) {
                mono_set_pending_exception (mono_get_exception_argument ("typeArguments", "Invalid generic arguments"));
                return NULL;
        }
@@ -2855,7 +2865,7 @@ ves_icall_RuntimeTypeHandle_HasInstantiation (MonoReflectionType *type)
                return FALSE;
 
        klass = mono_class_from_mono_type (type->type);
-       return klass->generic_class != NULL || klass->generic_container != NULL;
+       return mono_class_is_ginst (klass) || mono_class_is_gtd (klass);
 }
 
 ICALL_EXPORT gint32
@@ -3176,7 +3186,7 @@ ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this_arg, Mo
                return NULL;
        }
 
-       if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor") && !this_arg) {
+       if (mono_class_is_abstract (m->klass) && !strcmp (m->name, ".ctor") && !this_arg) {
                mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Cannot invoke constructor of an abstract class."));
                return NULL;
        }
@@ -4289,15 +4299,15 @@ ves_icall_RuntimeType_GetNestedTypes_native (MonoReflectionType *type, char *str
         * nested types that aren't generic.  In any case, the container of that
         * nested type would be the generic type definition.
         */
-       if (klass->generic_class)
-               klass = klass->generic_class->container_class;
+       if (mono_class_is_ginst (klass))
+               klass = mono_class_get_generic_class (klass)->container_class;
 
        res_array = g_ptr_array_new ();
        
        iter = NULL;
        while ((nested = mono_class_get_nested_types (klass, &iter))) {
                match = 0;
-               if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
+               if ((mono_class_get_flags (nested) & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
                        if (bflags & BFLAGS_Public)
                                match++;
                } else {
@@ -5085,10 +5095,10 @@ mono_method_get_equivalent_method (MonoMethod *method, MonoClass *klass)
                MonoGenericContext ctx;
                ctx.method_inst = inflated->context.method_inst;
                ctx.class_inst = inflated->context.class_inst;
-               if (klass->generic_class)
-                       ctx.class_inst = klass->generic_class->context.class_inst;
-               else if (klass->generic_container)
-                       ctx.class_inst = klass->generic_container->context.class_inst;
+               if (mono_class_is_ginst (klass))
+                       ctx.class_inst = mono_class_get_generic_class (klass)->context.class_inst;
+               else if (mono_class_is_gtd (klass))
+                       ctx.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
                result = mono_class_inflate_generic_method_full_checked (inflated->declaring, klass, &ctx, &error);
                g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
                return result;
@@ -6975,7 +6985,7 @@ ves_icall_Remoting_RemotingServices_GetVirtualMethod (
        mono_class_setup_vtable (klass);
        vtable = klass->vtable;
 
-       if (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
+       if (mono_class_is_interface (method->klass)) {
                gboolean variance_used = FALSE;
                /*MS fails with variant interfaces but it's the right thing to do anyway.*/
                int offs = mono_class_interface_offset_with_variance (klass, method->klass, &variance_used);
@@ -7038,7 +7048,7 @@ ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClas
        if (mono_error_set_pending_exception (&error))
                return NULL;
 
-       if (MONO_CLASS_IS_INTERFACE (klass) || (klass->flags & TYPE_ATTRIBUTE_ABSTRACT)) {
+       if (MONO_CLASS_IS_INTERFACE (klass) || mono_class_is_abstract (klass)) {
                mono_set_pending_exception (mono_get_exception_argument ("type", "Type cannot be instantiated"));
                return NULL;
        }
@@ -7345,9 +7355,9 @@ ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definiti
                return m;
 
        klass = method->klass;
-       if (klass->generic_class) {
+       if (mono_class_is_ginst (klass)) {
                generic_inst = mono_class_get_context (klass);
-               klass = klass->generic_class->container_class;
+               klass = mono_class_get_generic_class (klass)->container_class;
        }
 
 retry:
@@ -7384,9 +7394,9 @@ retry:
                                        return NULL;
                                }
                        }
-                       if (parent->generic_class) {
+                       if (mono_class_is_ginst (parent)) {
                                parent_inst = mono_class_get_context (parent);
-                               parent = parent->generic_class->container_class;
+                               parent = mono_class_get_generic_class (parent)->container_class;
                        }
 
                        mono_class_setup_vtable (parent);
@@ -7408,9 +7418,9 @@ retry:
 
                        generic_inst = NULL;
                }
-               if (klass->generic_class) {
+               if (mono_class_is_ginst (klass)) {
                        generic_inst = mono_class_get_context (klass);
-                       klass = klass->generic_class->container_class;
+                       klass = mono_class_get_generic_class (klass)->container_class;
                }
 
        }
@@ -7959,38 +7969,6 @@ ves_icall_System_ComponentModel_Win32Exception_W32ErrorMessage (guint32 code)
        return message;
 }
 
-ICALL_EXPORT gpointer
-ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcess (void)
-{
-       return GetCurrentProcess ();
-}
-
-ICALL_EXPORT MonoBoolean
-ves_icall_Microsoft_Win32_NativeMethods_GetExitCodeProcess (gpointer handle, gint32 *exitcode)
-{
-       return GetExitCodeProcess (handle, (guint32*) exitcode);
-}
-
-#ifndef HOST_WIN32
-static inline MonoBoolean
-mono_icall_close_process (gpointer handle)
-{
-       return CloseProcess (handle);
-}
-#endif /* !HOST_WIN32 */
-
-ICALL_EXPORT MonoBoolean
-ves_icall_Microsoft_Win32_NativeMethods_CloseProcess (gpointer handle)
-{
-       return mono_icall_close_process (handle);
-}
-
-ICALL_EXPORT MonoBoolean
-ves_icall_Microsoft_Win32_NativeMethods_TerminateProcess (gpointer handle, gint32 exitcode)
-{
-       return TerminateProcess (handle, exitcode);
-}
-
 #ifndef HOST_WIN32
 static inline gint32
 mono_icall_wait_for_input_idle (gpointer handle, gint32 milliseconds)
@@ -8005,74 +7983,12 @@ ves_icall_Microsoft_Win32_NativeMethods_WaitForInputIdle (gpointer handle, gint3
        return mono_icall_wait_for_input_idle (handle, milliseconds);
 }
 
-#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
-static inline MonoBoolean
-mono_icall_get_process_working_set_size (gpointer handle, gsize *min, gsize *max)
-{
-       return GetProcessWorkingSetSize (handle, min, max);
-}
-#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
-
-ICALL_EXPORT MonoBoolean
-ves_icall_Microsoft_Win32_NativeMethods_GetProcessWorkingSetSize (gpointer handle, gsize *min, gsize *max)
-{
-       return mono_icall_get_process_working_set_size (handle, min, max);
-}
-
-#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
-static inline MonoBoolean
-mono_icall_set_process_working_set_size (gpointer handle, gsize min, gsize max)
-{
-       return SetProcessWorkingSetSize (handle, min, max);
-}
-#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
-
-ICALL_EXPORT MonoBoolean
-ves_icall_Microsoft_Win32_NativeMethods_SetProcessWorkingSetSize (gpointer handle, gsize min, gsize max)
-{
-       return mono_icall_set_process_working_set_size (handle, min, max);
-}
-
-ICALL_EXPORT MonoBoolean
-ves_icall_Microsoft_Win32_NativeMethods_GetProcessTimes (gpointer handle, gint64 *creationtime, gint64 *exittime, gint64 *kerneltime, gint64 *usertime)
-{
-       return GetProcessTimes (handle, (LPFILETIME) creationtime, (LPFILETIME) exittime, (LPFILETIME) kerneltime, (LPFILETIME) usertime);
-}
-
 ICALL_EXPORT gint32
 ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcessId (void)
 {
        return mono_process_current_pid ();
 }
 
-#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
-static inline gint32
-mono_icall_get_priority_class (gpointer handle)
-{
-       return GetPriorityClass (handle);
-}
-#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
-
-ICALL_EXPORT gint32
-ves_icall_Microsoft_Win32_NativeMethods_GetPriorityClass (gpointer handle)
-{
-       return mono_icall_get_priority_class (handle);
-}
-
-#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
-static inline MonoBoolean
-mono_icall_set_priority_class (gpointer handle, gint32 priorityClass)
-{
-       return SetPriorityClass (handle, priorityClass);
-}
-#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
-
-ICALL_EXPORT MonoBoolean
-ves_icall_Microsoft_Win32_NativeMethods_SetPriorityClass (gpointer handle, gint32 priorityClass)
-{
-       return mono_icall_set_priority_class (handle, priorityClass);
-}
-
 ICALL_EXPORT MonoBoolean
 ves_icall_Mono_TlsProviderFactory_IsBtlsSupported (void)
 {
index 7f3260c0babc5887fef8335e55367356f1e08d6d..4fc6f218e1708a0ccc7c676f069f8743ef2f277b 100644 (file)
@@ -761,7 +761,7 @@ class_key_extract (gpointer value)
 static gpointer*
 class_next_value (gpointer value)
 {
-       MonoClass *klass = (MonoClass *)value;
+       MonoClassDef *klass = (MonoClassDef *)value;
 
        return (gpointer*)&klass->next_class_cache;
 }
index 3d85497bfe0a094a8154c6277ba693e8a910f157..3d76058d23314ce3dffb7247e88033eb50acdcf6 100644 (file)
@@ -319,7 +319,7 @@ mono_field_from_token_checked (MonoImage *image, guint32 token, MonoClass **retk
                }
        }
 
-       if (field && field->parent && !field->parent->generic_class && !field->parent->generic_container) {
+       if (field && field->parent && !mono_class_is_ginst (field->parent) && !mono_class_is_gtd (field->parent)) {
                mono_image_lock (image);
                mono_conc_hashtable_insert (image->field_cache, GUINT_TO_POINTER (token), field);
                mono_image_unlock (image);
@@ -362,15 +362,16 @@ find_method_in_class (MonoClass *klass, const char *name, const char *qname, con
        /* Search directly in the metadata to avoid calling setup_methods () */
        mono_error_init (error);
 
-       /* FIXME: !from_class->generic_class condition causes test failures. */
-       if (klass->type_token && !image_is_dynamic (klass->image) && !klass->methods && !klass->rank && klass == from_class && !from_class->generic_class) {
+       /* FIXME: !mono_class_is_ginst (from_class) condition causes test failures. */
+       if (klass->type_token && !image_is_dynamic (klass->image) && !klass->methods && !klass->rank && klass == from_class && !mono_class_is_ginst (from_class)) {
+               int first_idx = mono_class_get_first_method_idx (klass);
                for (i = 0; i < klass->method.count; ++i) {
                        guint32 cols [MONO_METHOD_SIZE];
                        MonoMethod *method;
                        const char *m_name;
                        MonoMethodSignature *other_sig;
 
-                       mono_metadata_decode_table_row (klass->image, MONO_TABLE_METHOD, klass->method.first + i, cols, MONO_METHOD_SIZE);
+                       mono_metadata_decode_table_row (klass->image, MONO_TABLE_METHOD, first_idx + i, cols, MONO_METHOD_SIZE);
 
                        m_name = mono_metadata_string_heap (klass->image, cols [MONO_METHOD_NAME]);
 
@@ -379,7 +380,7 @@ find_method_in_class (MonoClass *klass, const char *name, const char *qname, con
                                  (name && !strcmp (m_name, name))))
                                continue;
 
-                       method = mono_get_method_checked (klass->image, MONO_TOKEN_METHOD_DEF | (klass->method.first + i + 1), klass, NULL, error);
+                       method = mono_get_method_checked (klass->image, MONO_TOKEN_METHOD_DEF | (first_idx + i + 1), klass, NULL, error);
                        if (!mono_error_ok (error)) //bail out if we hit a loader error
                                return NULL;
                        if (method) {
@@ -668,7 +669,7 @@ mono_method_get_signature_checked (MonoMethod *method, MonoImage *image, guint32
                return mono_method_signature_checked (method, error);
        }
 
-       if (method->klass->generic_class)
+       if (mono_class_is_ginst (method->klass))
                return mono_method_signature_checked (method, error);
 
        if (image_is_dynamic (image)) {
@@ -854,7 +855,7 @@ method_from_memberref (MonoImage *image, guint32 idx, MonoGenericContext *typesp
                type = &klass->byval_arg;
 
                if (type->type != MONO_TYPE_ARRAY && type->type != MONO_TYPE_SZARRAY) {
-                       MonoClass *in_class = klass->generic_class ? klass->generic_class->container_class : klass;
+                       MonoClass *in_class = mono_class_is_ginst (klass) ? mono_class_get_generic_class (klass)->container_class : klass;
                        method = find_method (in_class, NULL, mname, sig, klass, error);
                        break;
                }
@@ -941,12 +942,12 @@ method_from_methodspec (MonoImage *image, MonoGenericContext *context, guint32 i
 
        klass = method->klass;
 
-       if (klass->generic_class) {
+       if (mono_class_is_ginst (klass)) {
                g_assert (method->is_inflated);
                method = ((MonoMethodInflated *) method)->declaring;
        }
 
-       new_context.class_inst = klass->generic_class ? klass->generic_class->context.class_inst : NULL;
+       new_context.class_inst = mono_class_is_ginst (klass) ? mono_class_get_generic_class (klass)->context.class_inst : NULL;
        new_context.method_inst = inst;
 
        method = mono_class_inflate_generic_method_full_checked (method, klass, &new_context, error);
@@ -1659,7 +1660,7 @@ mono_get_method_from_token (MonoImage *image, guint32 token, MonoClass *klass,
                sig = mono_metadata_blob_heap (image, cols [4]);
        /* size = */ mono_metadata_decode_blob_size (sig, &sig);
 
-       container = klass->generic_container;
+       container = mono_class_try_get_generic_container (klass);
 
        /* 
         * load_generic_params does a binary search so only call it if the method 
@@ -2374,10 +2375,10 @@ mono_method_signature_checked (MonoMethod *m, MonoError *error)
 
        sig = mono_metadata_blob_heap (img, sig_offset = mono_metadata_decode_row_col (&img->tables [MONO_TABLE_METHOD], idx - 1, MONO_METHOD_SIGNATURE));
 
-       g_assert (!m->klass->generic_class);
+       g_assert (!mono_class_is_ginst (m->klass));
        container = mono_method_get_generic_container (m);
        if (!container)
-               container = m->klass->generic_container;
+               container = mono_class_try_get_generic_container (m->klass);
 
        /* Generic signatures depend on the container so they cannot be cached */
        /* icall/pinvoke signatures cannot be cached cause we modify them below */
@@ -2579,7 +2580,7 @@ mono_method_get_header_checked (MonoMethod *method, MonoError *error)
         */
        container = mono_method_get_generic_container (method);
        if (!container)
-               container = method->klass->generic_container;
+               container = mono_class_try_get_generic_container (method->klass);
        return mono_metadata_parse_mh_full (img, container, (const char *)loc, error);
 }
 
@@ -2620,12 +2621,13 @@ mono_method_get_index (MonoMethod *method)
        mono_class_setup_methods (klass);
        if (mono_class_has_failure (klass))
                return 0;
+       int first_idx = mono_class_get_first_method_idx (klass);
        for (i = 0; i < klass->method.count; ++i) {
                if (method == klass->methods [i]) {
                        if (klass->image->uncompressed_metadata)
-                               return mono_metadata_translate_token_index (klass->image, MONO_TABLE_METHOD, klass->method.first + i + 1);
+                               return mono_metadata_translate_token_index (klass->image, MONO_TABLE_METHOD, first_idx + i + 1);
                        else
-                               return klass->method.first + i + 1;
+                               return first_idx + i + 1;
                }
        }
        return 0;
index e19613a182fcbbf5ee2988e0dd2e081c88d53bc5..1b4ff57b84bdc01134584c0681725ed591717d8c 100644 (file)
@@ -32,7 +32,7 @@ void
 mono_marshal_free_hglobal (void *ptr);
 
 gpointer
-mono_string_to_lpstr (MonoString *s);
+mono_string_to_utf8str (MonoString *s);
 #endif  /* HOST_WIN32 */
 
 #endif /* __MONO_METADATA_MARSHAL_INTERNALS_H__ */
index 25868130411243f01d4631ad0ca78928359e3bc1..69ee01dea9b5de6e817356e5a386cad3ac4992ad 100644 (file)
@@ -93,7 +93,7 @@ ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalUni (MonoString
 }
 
 gpointer
-mono_string_to_lpstr (MonoString *s)
+mono_string_to_utf8str (MonoString *s)
 {
        char *as, *tmp;
        glong len;
index a9a1042aee535ed693236c55c534486013e9e3ed..a743f83f6300731c27ee5dc55c9da46bcb76ef24 100644 (file)
@@ -82,6 +82,8 @@ static MonoNativeTlsKey load_type_info_tls_id;
 
 static gboolean use_aot_wrappers;
 
+static int class_marshal_info_count;
+
 static void ftnptr_eh_callback_default (guint32 gchandle);
 
 static MonoFtnPtrEHCallback ftnptr_eh_callback = ftnptr_eh_callback_default;
@@ -107,8 +109,10 @@ mono_marshal_string_to_utf16 (MonoString *s);
 static void *
 mono_marshal_string_to_utf16_copy (MonoString *s);
 
+#ifndef HOST_WIN32
 static gpointer
 mono_string_to_utf8str (MonoString *string_obj);
+#endif
 
 static MonoStringBuilder *
 mono_string_utf8_to_builder2 (char *text);
@@ -352,6 +356,10 @@ mono_marshal_init (void)
 
                mono_cominterop_init ();
                mono_remoting_init ();
+
+               mono_counters_register ("MonoClass::class_marshal_info_count count",
+                                                               MONO_COUNTER_METADATA | MONO_COUNTER_INT, &class_marshal_info_count);
+
        }
 }
 
@@ -1074,6 +1082,7 @@ mono_string_builder_to_utf16 (MonoStringBuilder *sb)
        return str;
 }
 
+#ifndef HOST_WIN32
 /* This is a JIT icall, it sets the pending exception and returns NULL on error. */
 static gpointer
 mono_string_to_utf8str (MonoString *s)
@@ -1083,6 +1092,7 @@ mono_string_to_utf8str (MonoString *s)
        mono_error_set_pending_exception (&error);
        return result;
 }
+#endif
 
 gpointer
 mono_string_to_ansibstr (MonoString *string_obj)
@@ -1964,7 +1974,7 @@ emit_struct_conv_full (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_obje
        }
 
        if (klass != mono_class_try_get_safehandle_class ()) {
-               if ((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT) {
+               if (mono_class_is_auto_layout (klass)) {
                        char *msg = g_strdup_printf ("Type %s which is passed to unmanaged code must have a StructLayout attribute.",
                                                                                 mono_type_full_name (&klass->byval_arg));
                        mono_mb_emit_exception_marshal_directive (mb, msg);
@@ -1999,7 +2009,7 @@ emit_struct_conv_full (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_obje
                         * the layout to the managed structure as well.
                         */
                        
-                       if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) && (usize == 0)) {
+                       if (mono_class_is_explicit_layout (klass) && (usize == 0)) {
                                if (MONO_TYPE_IS_REFERENCE (info->fields [i].field->type) ||
                                    ((!last_field && MONO_TYPE_IS_REFERENCE (info->fields [i + 1].field->type))))
                                        g_error ("Type %s which has an [ExplicitLayout] attribute cannot have a "
@@ -3264,7 +3274,7 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt
        MonoMethod *res;
        GHashTable *cache;
        gpointer cache_key = NULL;
-       SignaturePointerPair key;
+       SignaturePointerPair key = { NULL, NULL };
        SignaturePointerPair *new_key;
        int local_i, local_len, local_delegates, local_d, local_target, local_res;
        int pos0, pos1, pos2;
@@ -3322,7 +3332,7 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt
 
                container = mono_method_get_generic_container (method);
                if (!container)
-                       container = method->klass->generic_container;
+                       container = mono_class_try_get_generic_container (method->klass); //FIXME is this a case of a try?
                g_assert (container);
 
                invoke_sig = sig = mono_signature_no_pinvoke (method);
@@ -4938,8 +4948,7 @@ emit_marshal_vtype (EmitMarshalContext *m, int argnum, MonoType *t,
                        break;
                }
 
-               if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
-                       klass->blittable || klass->enumtype)
+               if (mono_class_is_explicit_layout (klass) || klass->blittable || klass->enumtype)
                        break;
 
                conv_arg = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
@@ -4985,8 +4994,7 @@ emit_marshal_vtype (EmitMarshalContext *m, int argnum, MonoType *t,
                        /* Have to change the signature since the vtype is passed byref */
                        m->csig->params [argnum - m->csig->hasthis] = &mono_defaults.int_class->byval_arg;
 
-                       if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
-                               klass->blittable || klass->enumtype)
+                       if (mono_class_is_explicit_layout (klass) || klass->blittable || klass->enumtype)
                                mono_mb_emit_ldarg_addr (mb, argnum);
                        else
                                mono_mb_emit_ldloc (mb, conv_arg);
@@ -5001,8 +5009,7 @@ emit_marshal_vtype (EmitMarshalContext *m, int argnum, MonoType *t,
                        break;
                }
 
-               if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
-                       klass->blittable || klass->enumtype) {
+               if (mono_class_is_explicit_layout (klass) || klass->blittable || klass->enumtype) {
                        mono_mb_emit_ldarg (mb, argnum);
                        break;
                }                       
@@ -5034,8 +5041,7 @@ emit_marshal_vtype (EmitMarshalContext *m, int argnum, MonoType *t,
                        break;
                }
 
-               if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
-                       klass->blittable || klass->enumtype)
+               if (mono_class_is_explicit_layout (klass) || klass->blittable || klass->enumtype)
                        break;
 
                if (t->byref) {
@@ -5063,8 +5069,7 @@ emit_marshal_vtype (EmitMarshalContext *m, int argnum, MonoType *t,
                break;
 
        case MARSHAL_ACTION_CONV_RESULT:
-               if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
-                       klass->blittable) {
+               if (mono_class_is_explicit_layout (klass) || klass->blittable) {
                        mono_mb_emit_stloc (mb, 3);
                        break;
                }
@@ -5083,8 +5088,7 @@ emit_marshal_vtype (EmitMarshalContext *m, int argnum, MonoType *t,
                break;
 
        case MARSHAL_ACTION_MANAGED_CONV_IN:
-               if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
-                       klass->blittable || klass->enumtype) {
+               if (mono_class_is_explicit_layout (klass) || klass->blittable || klass->enumtype) {
                        conv_arg = 0;
                        break;
                }
@@ -5116,11 +5120,8 @@ emit_marshal_vtype (EmitMarshalContext *m, int argnum, MonoType *t,
                break;
 
        case MARSHAL_ACTION_MANAGED_CONV_OUT:
-               if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
-                       klass->blittable || klass->enumtype) {
+               if (mono_class_is_explicit_layout (klass) || klass->blittable || klass->enumtype)
                        break;
-               }
-
                if (t->byref && (t->attrs & PARAM_ATTRIBUTE_IN) && !(t->attrs & PARAM_ATTRIBUTE_OUT))
                        break;
 
@@ -5143,8 +5144,7 @@ emit_marshal_vtype (EmitMarshalContext *m, int argnum, MonoType *t,
                break;
 
        case MARSHAL_ACTION_MANAGED_CONV_RESULT:
-               if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
-                       klass->blittable || klass->enumtype) {
+               if (mono_class_is_explicit_layout (klass) || klass->blittable || klass->enumtype) {
                        mono_mb_emit_stloc (mb, 3);
                        m->retobj_var = 0;
                        break;
@@ -5476,7 +5476,7 @@ emit_marshal_safehandle (EmitMarshalContext *m, int argnum, MonoType *t,
                MonoMethod *ctor = NULL;
                int intptr_handle_slot;
                
-               if (t->data.klass->flags & TYPE_ATTRIBUTE_ABSTRACT){
+               if (mono_class_is_abstract (t->data.klass)) {
                        mono_mb_emit_byte (mb, CEE_POP);
                        mono_mb_emit_exception_marshal_directive (mb, g_strdup ("Returned SafeHandles should not be abstract"));
                        break;
@@ -5935,7 +5935,7 @@ emit_marshal_object (EmitMarshalContext *m, int argnum, MonoType *t,
                }
 
                /* The class can not have an automatic layout */
-               if ((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT) {
+               if (mono_class_is_auto_layout (klass)) {
                        mono_mb_emit_auto_layout_exception (mb, klass);
                        break;
                }
@@ -6055,7 +6055,7 @@ emit_marshal_object (EmitMarshalContext *m, int argnum, MonoType *t,
                }
 
                /* The class can not have an automatic layout */
-               if ((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT) {
+               if (mono_class_is_auto_layout (klass)) {
                        mono_mb_emit_auto_layout_exception (mb, klass);
                        break;
                }
@@ -7516,7 +7516,7 @@ mono_marshal_emit_native_wrapper (MonoImage *image, MonoMethodBuilder *mb, MonoM
        if (MONO_TYPE_ISSTRUCT (sig->ret)) {
                MonoClass *klass = mono_class_from_mono_type (sig->ret);
                mono_class_init (klass);
-               if (!(((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) || klass->blittable)) {
+               if (!(mono_class_is_explicit_layout (klass) || klass->blittable)) {
                        /* This is used by emit_marshal_vtype (), but it needs to go right before the call */
                        mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
                        mono_mb_emit_byte (mb, CEE_MONO_VTADDR);
@@ -8255,7 +8255,7 @@ mono_marshal_emit_managed_wrapper (MonoMethodBuilder *mb, MonoMethodSignature *i
        if (MONO_TYPE_ISSTRUCT (sig->ret)) {
                MonoClass *klass = mono_class_from_mono_type (sig->ret);
                mono_class_init (klass);
-               if (!(((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) || klass->blittable)) {
+               if (!(mono_class_is_explicit_layout (klass) || klass->blittable)) {
                        /* This is used by emit_marshal_vtype (), but it needs to go right before the call */
                        mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
                        mono_mb_emit_byte (mb, CEE_MONO_VTADDR);
@@ -9280,7 +9280,7 @@ mono_marshal_get_synchronized_inner_wrapper (MonoMethod *method)
                method = ((MonoMethodInflated*)method)->declaring;
                container = mono_method_get_generic_container (method);
                if (!container)
-                       container = method->klass->generic_container;
+                       container = mono_class_try_get_generic_container (method->klass); //FIXME is this a case of a try?
                g_assert (container);
        }
 
@@ -9334,7 +9334,7 @@ mono_marshal_get_synchronized_wrapper (MonoMethod *method)
                method = ((MonoMethodInflated*)method)->declaring;
                container = mono_method_get_generic_container (method);
                if (!container)
-                       container = method->klass->generic_container;
+                       container = mono_class_try_get_generic_container (method->klass); //FIXME is this a case of a try?
                g_assert (container);
        }
 
@@ -9561,7 +9561,7 @@ is_monomorphic_array (MonoClass *klass)
                return FALSE;
 
        element_class = klass->element_class;
-       return (element_class->flags & TYPE_ATTRIBUTE_SEALED) || element_class->valuetype;
+       return mono_class_is_sealed (element_class) || element_class->valuetype;
 }
 
 static int
@@ -9581,7 +9581,7 @@ get_virtual_stelemref_kind (MonoClass *element_class)
        /*Arrays are sealed but are covariant on their element type, We can't use any of the fast paths.*/
        if (mono_class_is_marshalbyref (element_class) || element_class->rank || mono_class_has_variant_generic_params (element_class))
                return STELEMREF_COMPLEX;
-       if (element_class->flags & TYPE_ATTRIBUTE_SEALED)
+       if (mono_class_is_sealed (element_class))
                return STELEMREF_SEALED_CLASS;
        return STELEMREF_CLASS;
 }
@@ -9940,14 +9940,14 @@ get_virtual_stelemref_wrapper (int kind)
                /* uiid = klass->interface_id; */
                mono_mb_emit_ldloc (mb, aklass);
                mono_mb_emit_ldflda (mb, MONO_STRUCT_OFFSET (MonoClass, interface_id));
-               mono_mb_emit_byte (mb, CEE_LDIND_U2);
+               mono_mb_emit_byte (mb, CEE_LDIND_U4);
                mono_mb_emit_stloc (mb, uiid);
 
                /*if (uiid > vt->max_interface_id)*/
                mono_mb_emit_ldloc (mb, uiid);
                mono_mb_emit_ldloc (mb, vtable);
                mono_mb_emit_ldflda (mb, MONO_STRUCT_OFFSET (MonoVTable, max_interface_id));
-               mono_mb_emit_byte (mb, CEE_LDIND_U2);
+               mono_mb_emit_byte (mb, CEE_LDIND_U4);
                b2 = mono_mb_emit_branch (mb, CEE_BGT_UN);
 
                /* if (!(vt->interface_bitmap [(uiid) >> 3] & (1 << ((uiid)&7)))) */
@@ -10798,7 +10798,7 @@ ves_icall_System_Runtime_InteropServices_Marshal_SizeOf (MonoReflectionType *rty
                return 0;
        }
 
-       layout = (klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK);
+       layout = (mono_class_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK);
 
        if (type->type == MONO_TYPE_PTR || type->type == MONO_TYPE_FNPTR) {
                return sizeof (gpointer);
@@ -11277,7 +11277,7 @@ mono_marshal_load_type_info (MonoClass* klass)
                count++;
        }
 
-       layout = klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK;
+       layout = mono_class_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK;
 
        /* The mempool is protected by the loader lock */
        info = (MonoMarshalType *)mono_image_alloc0 (klass->image, MONO_SIZEOF_MARSHAL_TYPE + sizeof (MonoMarshalField) * count);
@@ -11383,6 +11383,7 @@ mono_marshal_load_type_info (MonoClass* klass)
                /*We do double-checking locking on marshal_info */
                mono_memory_barrier ();
                klass->marshal_info = info;
+               ++class_marshal_info_count;
        }
        mono_marshal_unlock ();
 
@@ -11644,11 +11645,10 @@ mono_marshal_asany (MonoObject *o, MonoMarshalNative string_encoding, int param_
 
                klass = t->data.klass;
 
-               if ((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT)
+               if (mono_class_is_auto_layout (klass))
                        break;
 
-               if (klass->valuetype && (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
-                       klass->blittable || klass->enumtype))
+               if (klass->valuetype && (mono_class_is_explicit_layout (klass) || klass->blittable || klass->enumtype))
                        return mono_object_unbox (o);
 
                res = mono_marshal_alloc (mono_class_native_size (klass, NULL), &error);
@@ -11709,8 +11709,7 @@ mono_marshal_free_asany (MonoObject *o, gpointer ptr, MonoMarshalNative string_e
        case MONO_TYPE_VALUETYPE: {
                klass = t->data.klass;
 
-               if (klass->valuetype && (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
-                                                                klass->blittable || klass->enumtype))
+               if (klass->valuetype && (mono_class_is_explicit_layout (klass) || klass->blittable || klass->enumtype))
                        break;
 
                if (param_attrs & PARAM_ATTRIBUTE_OUT) {
index 3a4c22860f7c7b022e10743442037436c061c718..36a954cd8b036e73716d1d806fd2a83a465f7098 100644 (file)
@@ -2937,7 +2937,7 @@ mono_metadata_get_generic_inst (int type_argc, MonoType **type_argv)
 static gboolean
 mono_metadata_is_type_builder_generic_type_definition (MonoClass *container_class, MonoGenericInst *inst, gboolean is_dynamic)
 {
-       MonoGenericContainer *container = container_class->generic_container
+       MonoGenericContainer *container = mono_class_get_generic_container (container_class)
 
        if (!is_dynamic || container_class->wastypebuilder || container->type_argc != inst->type_argc)
                return FALSE;
@@ -2959,6 +2959,8 @@ mono_metadata_lookup_generic_class (MonoClass *container_class, MonoGenericInst
        MonoImageSet *set;
        CollectData data;
 
+       g_assert (mono_class_get_generic_container (container_class)->type_argc == inst->type_argc);
+
        memset (&helper, 0, sizeof(helper)); // act like g_new0
        helper.container_class = container_class;
        helper.context.class_inst = inst;
@@ -2994,7 +2996,7 @@ mono_metadata_lookup_generic_class (MonoClass *container_class, MonoGenericInst
        gclass->context.class_inst = inst;
        gclass->context.method_inst = NULL;
        gclass->owner = set;
-       if (inst == container_class->generic_container->context.class_inst && !is_tb_open)
+       if (inst == mono_class_get_generic_container (container_class)->context.class_inst && !is_tb_open)
                gclass->cached_class = container_class;
 
        g_hash_table_insert (set->gclass_cache, gclass, gclass);
@@ -3089,7 +3091,7 @@ do_mono_metadata_parse_generic_class (MonoType *type, MonoImage *m, MonoGenericC
                return FALSE;
 
        gklass = mono_class_from_mono_type (gtype);
-       if (!gklass->generic_container) {
+       if (!mono_class_is_gtd (gklass)) {
                mono_error_set_bad_image (error, m, "Generic instance with non-generic definition");
                return FALSE;
        }
@@ -4804,7 +4806,7 @@ static gboolean
 _mono_metadata_generic_class_container_equal (const MonoGenericClass *g1, MonoClass *c2, gboolean signature_only)
 {
        MonoGenericInst *i1 = g1->context.class_inst;
-       MonoGenericInst *i2 = c2->generic_container->context.class_inst;
+       MonoGenericInst *i2 = mono_class_get_generic_container (c2)->context.class_inst;
 
        if (!mono_metadata_class_equal (g1->container_class, c2, signature_only))
                return FALSE;
@@ -4959,12 +4961,12 @@ mono_metadata_class_equal (MonoClass *c1, MonoClass *c2, gboolean signature_only
 {
        if (c1 == c2)
                return TRUE;
-       if (c1->generic_class && c2->generic_class)
-               return _mono_metadata_generic_class_equal (c1->generic_class, c2->generic_class, signature_only);
-       if (c1->generic_class && c2->generic_container)
-               return _mono_metadata_generic_class_container_equal (c1->generic_class, c2, signature_only);
-       if (c1->generic_container && c2->generic_class)
-               return _mono_metadata_generic_class_container_equal (c2->generic_class, c1, signature_only);
+       if (mono_class_is_ginst (c1) && mono_class_is_ginst (c2))
+               return _mono_metadata_generic_class_equal (mono_class_get_generic_class (c1), mono_class_get_generic_class (c2), signature_only);
+       if (mono_class_is_ginst (c1) && mono_class_is_gtd (c2))
+               return _mono_metadata_generic_class_container_equal (mono_class_get_generic_class (c1), c2, signature_only);
+       if (mono_class_is_gtd (c1) && mono_class_is_ginst (c2))
+               return _mono_metadata_generic_class_container_equal (mono_class_get_generic_class (c2), c1, signature_only);
        if ((c1->byval_arg.type == MONO_TYPE_VAR) && (c2->byval_arg.type == MONO_TYPE_VAR))
                return mono_metadata_generic_param_equal_internal (
                        c1->byval_arg.data.generic_param, c2->byval_arg.data.generic_param, signature_only);
@@ -6610,10 +6612,10 @@ mono_metadata_get_corresponding_field_from_generic_type_definition (MonoClassFie
        MonoClass *gtd;
        int offset;
 
-       if (!field->parent->generic_class)
+       if (!mono_class_is_ginst (field->parent))
                return field;
 
-       gtd = field->parent->generic_class->container_class;
+       gtd = mono_class_get_generic_class (field->parent)->container_class;
        offset = field - field->parent->fields;
        return gtd->fields + offset;
 }
@@ -6628,10 +6630,10 @@ mono_metadata_get_corresponding_event_from_generic_type_definition (MonoEvent *e
        MonoClass *gtd;
        int offset;
 
-       if (!event->parent->generic_class)
+       if (!mono_class_is_ginst (event->parent))
                return event;
 
-       gtd = event->parent->generic_class->container_class;
+       gtd = mono_class_get_generic_class (event->parent)->container_class;
        offset = event - event->parent->ext->events;
        return gtd->ext->events + offset;
 }
@@ -6646,10 +6648,10 @@ mono_metadata_get_corresponding_property_from_generic_type_definition (MonoPrope
        MonoClass *gtd;
        int offset;
 
-       if (!property->parent->generic_class)
+       if (!mono_class_is_ginst (property->parent))
                return property;
 
-       gtd = property->parent->generic_class->container_class;
+       gtd = mono_class_get_generic_class (property->parent)->container_class;
        offset = property - property->parent->ext->properties;
        return gtd->ext->properties + offset;
 }
index 6036fe3ae7dcf7e576e50f2af39f30d8ede9410e..d8e48318b4da77868fe8e06b40810e31849b6402 100644 (file)
@@ -15,9 +15,9 @@ MONO_BEGIN_DECLS
 #define MONO_TYPE_IS_POINTER(t) mono_type_is_pointer (t)
 #define MONO_TYPE_IS_REFERENCE(t) mono_type_is_reference (t)
 
-#define MONO_CLASS_IS_INTERFACE(c) ((c->flags & TYPE_ATTRIBUTE_INTERFACE) || (c->byval_arg.type == MONO_TYPE_VAR) || (c->byval_arg.type == MONO_TYPE_MVAR))
+#define MONO_CLASS_IS_INTERFACE(c) ((mono_class_get_flags (c) & TYPE_ATTRIBUTE_INTERFACE) || (c->byval_arg.type == MONO_TYPE_VAR) || (c->byval_arg.type == MONO_TYPE_MVAR))
 
-#define MONO_CLASS_IS_IMPORT(c) ((c->flags & TYPE_ATTRIBUTE_IMPORT))
+#define MONO_CLASS_IS_IMPORT(c) ((mono_class_get_flags (c) & TYPE_ATTRIBUTE_IMPORT))
 
 typedef struct _MonoClass MonoClass;
 typedef struct _MonoDomain MonoDomain;
index b2cdf6a9fe9cb65c3665ab51b725630c161e7d7c..1a60d2d85f36320dfb29e68a5d64e3dee4793a03 100644 (file)
@@ -349,7 +349,8 @@ typedef enum {
 struct _MonoInternalThread {
        MonoObject  obj;
        volatile int lock_thread_id; /* to be used as the pre-shifted thread id in thin locks. Used for appdomain_ref push/pop */
-       HANDLE      handle;
+       MonoThreadHandle *handle;
+       HANDLE native_handle;
        MonoArray  *cached_culture_info;
        gunichar2  *name;
        guint32     name_len;
@@ -382,6 +383,7 @@ struct _MonoInternalThread {
        gsize abort_protected_block_count;
        gint32 priority;
        GPtrArray *owned_mutexes;
+       MonoOSEvent *suspended;
        /* 
         * These fields are used to avoid having to increment corlib versions
         * when a new field is added to this structure.
index e4965a512a758da60f6db8a0512e36588a3b3bce..5c78288ec8b20f808fa2db0e74d9612e7ac817b3 100644 (file)
@@ -238,6 +238,8 @@ DECL_OFFSET(GSharedVtCallInfo, gsharedvt_in)
 #endif
 
 #if defined(TARGET_ARM64)
+DECL_OFFSET (MonoContext, has_fregs)
+
 DECL_OFFSET(GSharedVtCallInfo, stack_usage)
 DECL_OFFSET(GSharedVtCallInfo, gsharedvt_in)
 DECL_OFFSET(GSharedVtCallInfo, ret_marshal)
index 5a57b2fc6d04d7921143f2a9197298417adba2bc..c25a107fdeb502712987c0c7b5671e8258b1f49d 100644 (file)
@@ -1406,14 +1406,14 @@ build_imt_slots (MonoClass *klass, MonoVTable *vt, MonoDomain *domain, gpointer*
                for (method_slot_in_interface = 0; method_slot_in_interface < iface->method.count; method_slot_in_interface++) {
                        MonoMethod *method;
 
-                       if (slot_num >= 0 && iface->is_inflated) {
+                       if (slot_num >= 0 && mono_class_is_ginst (iface)) {
                                /*
                                 * The imt slot of the method is the same as for its declaring method,
                                 * see the comment in mono_method_get_imt_slot (), so we can
                                 * avoid inflating methods which will be discarded by 
                                 * add_imt_builder_entry anyway.
                                 */
-                               method = mono_class_get_method_by_index (iface->generic_class->container_class, method_slot_in_interface);
+                               method = mono_class_get_method_by_index (mono_class_get_generic_class (iface)->container_class, method_slot_in_interface);
                                if (mono_method_get_imt_slot (method) != slot_num) {
                                        vt_slot ++;
                                        continue;
@@ -1905,7 +1905,7 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *klass, MonoErro
        if (!klass->vtable_size)
                mono_class_setup_vtable (klass);
 
-       if (klass->generic_class && !klass->vtable)
+       if (mono_class_is_ginst (klass) && !klass->vtable)
                mono_class_check_vtable_constraints (klass, NULL);
 
        /* Initialize klass->has_finalize */
@@ -2202,7 +2202,8 @@ mono_class_proxy_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, Mono
        MONO_REQ_GC_UNSAFE_MODE;
 
        MonoVTable *vt, *pvt;
-       int i, j, vtsize, max_interface_id, extra_interface_vtsize = 0;
+       int i, j, vtsize, extra_interface_vtsize = 0;
+       guint32 max_interface_id;
        MonoClass *k;
        GSList *extra_interfaces = NULL;
        MonoClass *klass = remote_class->proxy_class;
@@ -2290,7 +2291,7 @@ mono_class_proxy_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, Mono
                        pvt->vtable [i] = NULL;
        }
 
-       if (klass->flags & TYPE_ATTRIBUTE_ABSTRACT) {
+       if (mono_class_is_abstract (klass)) {
                /* create trampolines for abstract methods */
                for (k = klass; k; k = k->parent) {
                        MonoMethod* m;
@@ -2448,7 +2449,7 @@ create_remote_class_key (MonoRemoteClass *remote_class, MonoClass *extra_class)
        int i, j;
        
        if (remote_class == NULL) {
-               if (extra_class->flags & TYPE_ATTRIBUTE_INTERFACE) {
+               if (mono_class_is_interface (extra_class)) {
                        key = (void **)g_malloc (sizeof(gpointer) * 3);
                        key [0] = GINT_TO_POINTER (2);
                        key [1] = mono_defaults.marshalbyrefobject_class;
@@ -2459,7 +2460,7 @@ create_remote_class_key (MonoRemoteClass *remote_class, MonoClass *extra_class)
                        key [1] = extra_class;
                }
        } else {
-               if (extra_class != NULL && (extra_class->flags & TYPE_ATTRIBUTE_INTERFACE)) {
+               if (extra_class != NULL && mono_class_is_interface (extra_class)) {
                        key = (void **)g_malloc (sizeof(gpointer) * (remote_class->interface_count + 3));
                        key [0] = GINT_TO_POINTER (remote_class->interface_count + 2);
                        key [1] = remote_class->proxy_class;
@@ -2548,7 +2549,7 @@ mono_remote_class (MonoDomain *domain, MonoString *class_name, MonoClass *proxy_
        g_free (key);
        key = mp_key;
 
-       if (proxy_class->flags & TYPE_ATTRIBUTE_INTERFACE) {
+       if (mono_class_is_interface (proxy_class)) {
                rc = (MonoRemoteClass *)mono_domain_alloc (domain, MONO_SIZEOF_REMOTE_CLASS + sizeof(MonoClass*));
                rc->interface_count = 1;
                rc->interfaces [0] = proxy_class;
@@ -2595,7 +2596,7 @@ clone_remote_class (MonoDomain *domain, MonoRemoteClass* remote_class, MonoClass
        g_free (key);
        key = mp_key;
 
-       if (extra_class->flags & TYPE_ATTRIBUTE_INTERFACE) {
+       if (mono_class_is_interface (extra_class)) {
                int i,j;
                rc = (MonoRemoteClass *)mono_domain_alloc (domain, MONO_SIZEOF_REMOTE_CLASS + sizeof(MonoClass*) * (remote_class->interface_count + 1));
                rc->proxy_class = remote_class->proxy_class;
@@ -2696,7 +2697,7 @@ mono_upgrade_remote_class (MonoDomain *domain, MonoObject *proxy_object, MonoCla
        tproxy = (MonoTransparentProxy*) proxy_object;
        remote_class = tproxy->remote_class;
        
-       if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
+       if (mono_class_is_interface (klass)) {
                int i;
                redo_vtable = TRUE;
                for (i = 0; i < remote_class->interface_count && redo_vtable; i++)
@@ -2767,7 +2768,7 @@ mono_object_get_virtual_method (MonoObject *obj, MonoMethod *method)
 
        /* check method->slot is a valid index: perform isinstance? */
        if (method->slot != -1) {
-               if (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
+               if (mono_class_is_interface (method->klass)) {
                        if (!is_proxy) {
                                gboolean variance_used = FALSE;
                                int iface_offset = mono_class_interface_offset_with_variance (klass, method->klass, &variance_used);
@@ -6487,7 +6488,7 @@ mono_object_isinst_checked (MonoObject *obj, MonoClass *klass, MonoError *error)
        if (!klass->inited)
                mono_class_init (klass);
 
-       if (mono_class_is_marshalbyref (klass) || (klass->flags & TYPE_ATTRIBUTE_INTERFACE)) {
+       if (mono_class_is_marshalbyref (klass) || mono_class_is_interface (klass)) {
                result = mono_object_isinst_mbyref_checked (obj, klass, error);
                return result;
        }
@@ -6523,7 +6524,7 @@ mono_object_isinst_mbyref_checked (MonoObject *obj, MonoClass *klass, MonoError
 
        vt = obj->vtable;
        
-       if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
+       if (mono_class_is_interface (klass)) {
                if (MONO_VTABLE_IMPLEMENTS_INTERFACE (vt, klass->interface_id)) {
                        return obj;
                }
@@ -7843,7 +7844,7 @@ mono_delegate_ctor (MonoObject *this_obj, MonoObject *target, gpointer addr, Mon
                ji = mono_jit_info_table_find (mono_get_root_domain (), (char *)mono_get_addr_from_ftnptr (addr));
        if (ji) {
                method = mono_jit_info_get_method (ji);
-               g_assert (!method->klass->generic_container);
+               g_assert (!mono_class_is_gtd (method->klass));
        }
 
        return mono_delegate_ctor_with_method (this_obj, target, addr, method, error);
diff --git a/mono/metadata/process-internals.h b/mono/metadata/process-internals.h
deleted file mode 100644 (file)
index cfc34e8..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2016 Microsoft
- * Licensed under the MIT license. See LICENSE file in the project root for full license information.
- */
-#ifndef __MONO_METADATA_PROCESS_INTERNALS_H__
-#define __MONO_METADATA_PROCESS_INTERNALS_H__
-
-#include <config.h>
-#include <glib.h>
-
-// On Windows platform implementation of bellow methods are hosted in separate source file
-// process-windows.c or process-windows-*.c. On other platforms the implementation is still keept
-// in process.c still declared as static and in some places even inlined.
-#ifdef HOST_WIN32
-gchar*
-mono_process_quote_path (const gchar *path);
-
-gchar*
-mono_process_unquote_application_name (gchar *path);
-
-gboolean
-mono_process_get_shell_arguments (MonoProcessStartInfo *proc_start_info, gunichar2 **shell_path,
-                                 MonoString **cmd);
-#endif  /* HOST_WIN32 */
-
-// On platforms not using classic WIN API support the  implementation of bellow methods are hosted in separate source file
-// process-windows-*.c. On platforms using classic WIN API the implementation is still keept in process.c and still declared
-// static and in some places even inlined.
-#if !G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
-void
-process_get_fileversion (MonoObject *filever, gunichar2 *filename, MonoError *error);
-
-void
-mono_process_init_startup_info (HANDLE stdin_handle, HANDLE stdout_handle,
-                               HANDLE stderr_handle,STARTUPINFO *startinfo);
-
-gboolean
-mono_process_create_process (MonoProcInfo *mono_process_info, gunichar2 *shell_path, MonoString *cmd,
-                            guint32 creation_flags, gchar *env_vars, gunichar2 *dir, STARTUPINFO *start_info,
-                            PROCESS_INFORMATION *process_info);
-#endif  /* !G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
-
-// Shared between all platforms and implemented in process.c.
-gboolean
-mono_process_complete_path (const gunichar2 *appname, gchar **completed);
-
-#endif /* __MONO_METADATA_PROCESS_INTERNALS_H__ */
diff --git a/mono/metadata/process-windows-internals.h b/mono/metadata/process-windows-internals.h
deleted file mode 100644 (file)
index 68721fa..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2016 Microsoft
- * Licensed under the MIT license. See LICENSE file in the project root for full license information.
- */
-#ifndef __MONO_METADATA_PROCESS_WINDOWS_INTERNALS_H__
-#define __MONO_METADATA_PROCESS_WINDOWS_INTERNALS_H__
-
-#include <config.h>
-#include <glib.h>
-
-#ifdef HOST_WIN32
-#include "mono/metadata/process.h"
-#include "mono/metadata/process-internals.h"
-#include "mono/metadata/object.h"
-#include "mono/metadata/object-internals.h"
-#include "mono/metadata/exception.h"
-
-// On platforms not using classic WIN API support the  implementation of bellow methods are hosted in separate source file
-// process-windows-*.c. On platforms using classic WIN API the implementation is still keept in process.c and still declared
-// static and in some places even inlined.
-#if !G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
-gboolean
-mono_process_win_enum_processes (DWORD *pids, DWORD count, DWORD *needed);
-#endif  /* !G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
-
-#endif /* HOST_WIN32 */
-
-#endif /* __MONO_METADATA_PROCESS_WINDOWS_INTERNALS_H__ */
diff --git a/mono/metadata/process-windows-uwp.c b/mono/metadata/process-windows-uwp.c
deleted file mode 100644 (file)
index 905555f..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * process-windows-uwp.c: UWP process support for Mono.
- *
- * Copyright 2016 Microsoft
- * Licensed under the MIT license. See LICENSE file in the project root for full license information.
-*/
-#include <config.h>
-#include <glib.h>
-
-#if G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT)
-#include <Windows.h>
-#include "mono/metadata/process-windows-internals.h"
-
-gboolean
-mono_process_win_enum_processes (DWORD *pids, DWORD count, DWORD *needed)
-{
-       g_unsupported_api ("EnumProcesses");
-       *needed = 0;
-       SetLastError (ERROR_NOT_SUPPORTED);
-
-       return FALSE;
-}
-
-HANDLE
-ves_icall_System_Diagnostics_Process_GetProcess_internal (guint32 pid)
-{
-       HANDLE handle;
-
-       /* GetCurrentProcess returns a pseudo-handle, so use
-        * OpenProcess instead
-        */
-       handle = OpenProcess (PROCESS_ALL_ACCESS, TRUE, pid);
-       if (handle == NULL)
-               /* FIXME: Throw an exception */
-               return NULL;
-       return handle;
-}
-
-void
-process_get_fileversion (MonoObject *filever, gunichar2 *filename, MonoError *error)
-{
-       g_unsupported_api ("GetFileVersionInfoSize, GetFileVersionInfo, VerQueryValue, VerLanguageName");
-
-       mono_error_init (error);
-       mono_error_set_not_supported (error, G_UNSUPPORTED_API, "GetFileVersionInfoSize, GetFileVersionInfo, VerQueryValue, VerLanguageName");
-
-       SetLastError (ERROR_NOT_SUPPORTED);
-}
-
-MonoObject*
-process_add_module (HANDLE process, HMODULE mod, gunichar2 *filename, gunichar2 *modulename, MonoClass *proc_class, MonoError *error)
-{
-       g_unsupported_api ("GetModuleInformation");
-
-       mono_error_init (error);
-       mono_error_set_not_supported (error, G_UNSUPPORTED_API, "GetModuleInformation");
-
-       SetLastError (ERROR_NOT_SUPPORTED);
-
-       return NULL;
-}
-
-MonoArray *
-ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObject *this_obj, HANDLE process)
-{
-       MonoError mono_error;
-       mono_error_init (&mono_error);
-
-       g_unsupported_api ("EnumProcessModules, GetModuleBaseName, GetModuleFileNameEx");
-
-       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "EnumProcessModules, GetModuleBaseName, GetModuleFileNameEx");
-       mono_error_set_pending_exception (&mono_error);
-
-       SetLastError (ERROR_NOT_SUPPORTED);
-
-       return NULL;
-}
-
-MonoBoolean
-ves_icall_System_Diagnostics_Process_ShellExecuteEx_internal (MonoProcessStartInfo *proc_start_info, MonoProcInfo *process_info)
-{
-       MonoError mono_error;
-       mono_error_init (&mono_error);
-
-       g_unsupported_api ("ShellExecuteEx");
-
-       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "ShellExecuteEx");
-       mono_error_set_pending_exception (&mono_error);
-
-       process_info->pid = (guint32)(-ERROR_NOT_SUPPORTED);
-       SetLastError (ERROR_NOT_SUPPORTED);
-
-       return FALSE;
-}
-
-MonoString *
-ves_icall_System_Diagnostics_Process_ProcessName_internal (HANDLE process)
-{
-       MonoError error;
-       MonoString *string;
-       gunichar2 name[MAX_PATH];
-       guint32 len;
-
-       len = GetModuleFileName (NULL, name, G_N_ELEMENTS (name));
-       if (len == 0)
-               return NULL;
-
-       string = mono_string_new_utf16_checked (mono_domain_get (), name, len, &error);
-       if (!mono_error_ok (&error))
-               mono_error_set_pending_exception (&error);
-
-       return string;
-}
-
-void
-mono_process_init_startup_info (HANDLE stdin_handle, HANDLE stdout_handle, HANDLE stderr_handle, STARTUPINFO *startinfo)
-{
-       startinfo->cb = sizeof(STARTUPINFO);
-       startinfo->dwFlags = 0;
-       startinfo->hStdInput = INVALID_HANDLE_VALUE;
-       startinfo->hStdOutput = INVALID_HANDLE_VALUE;
-       startinfo->hStdError = INVALID_HANDLE_VALUE;
-       return;
-}
-
-gboolean
-mono_process_create_process (MonoProcInfo *mono_process_info, gunichar2 *shell_path, MonoString *cmd, guint32 creation_flags,
-                            gchar *env_vars, gunichar2 *dir, STARTUPINFO *start_info, PROCESS_INFORMATION *process_info)
-{
-       MonoError       mono_error;
-       gchar           *api_name = "";
-
-       if (mono_process_info->username) {
-               api_name = "CreateProcessWithLogonW";
-       } else {
-               api_name = "CreateProcess";
-       }
-
-       memset (&process_info, 0, sizeof (PROCESS_INFORMATION));
-       g_unsupported_api (api_name);
-
-       mono_error_init (&mono_error);
-       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, api_name);
-       mono_error_set_pending_exception (&mono_error);
-
-       SetLastError (ERROR_NOT_SUPPORTED);
-
-       return FALSE;
-}
-
-#else /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
-
-#ifdef _MSC_VER
-// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
-void __mono_win32_process_windows_uwp_quiet_lnk4221(void) {}
-#endif
-#endif /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
diff --git a/mono/metadata/process-windows.c b/mono/metadata/process-windows.c
deleted file mode 100644 (file)
index 5bf0b7d..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * process-windows.c: Windows process support.
- *
- * Copyright 2016 Microsoft
- * Licensed under the MIT license. See LICENSE file in the project root for full license information.
- */
-
-#include <config.h>
-#include <glib.h>
-
-#if defined(HOST_WIN32)
-#include <winsock2.h>
-#include <windows.h>
-#include "mono/metadata/process-windows-internals.h"
-
-#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
-static inline gboolean
-mono_process_win_enum_processes (DWORD *pids, DWORD count, DWORD *needed)
-{
-       return EnumProcesses (pids, count, needed);
-}
-#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
-
-MonoArray *
-ves_icall_System_Diagnostics_Process_GetProcesses_internal (void)
-{
-       MonoError error;
-       MonoArray *procs;
-       gboolean ret;
-       DWORD needed;
-       int count;
-       DWORD *pids;
-
-       count = 512;
-       do {
-               pids = g_new0 (DWORD, count);
-               ret = mono_process_win_enum_processes (pids, count * sizeof (guint32), &needed);
-               if (ret == FALSE) {
-                       MonoException *exc;
-
-                       g_free (pids);
-                       pids = NULL;
-                       exc = mono_get_exception_not_supported ("This system does not support EnumProcesses");
-                       mono_set_pending_exception (exc);
-                       return NULL;
-               }
-               if (needed < (count * sizeof (guint32)))
-                       break;
-               g_free (pids);
-               pids = NULL;
-               count = (count * 3) / 2;
-       } while (TRUE);
-
-       count = needed / sizeof (guint32);
-       procs = mono_array_new_checked (mono_domain_get (), mono_get_int32_class (), count, &error);
-       if (mono_error_set_pending_exception (&error)) {
-               g_free (pids);
-               return NULL;
-       }
-
-       memcpy (mono_array_addr (procs, guint32, 0), pids, needed);
-       g_free (pids);
-       pids = NULL;
-
-       return procs;
-}
-
-gchar*
-mono_process_quote_path (const gchar *path)
-{
-       gchar *res = g_shell_quote (path);
-       gchar *q = res;
-       while (*q) {
-               if (*q == '\'')
-                       *q = '\"';
-               q++;
-       }
-       return res;
-}
-
-gchar*
-mono_process_unquote_application_name (gchar *appname)
-{
-       size_t len = strlen (appname);
-       if (len) {
-               if (appname[len-1] == '\"')
-                       appname[len-1] = '\0';
-               if (appname[0] == '\"')
-                       appname++;
-       }
-
-       return appname;
-}
-
-gboolean
-mono_process_get_shell_arguments (MonoProcessStartInfo *proc_start_info, gunichar2 **shell_path, MonoString **cmd)
-{
-       gchar           *spath = NULL;
-       gchar           *new_cmd, *cmd_utf8;
-       MonoError       mono_error;
-
-       *shell_path = NULL;
-       *cmd = proc_start_info->arguments;
-
-       mono_process_complete_path (mono_string_chars (proc_start_info->filename), &spath);
-       if (spath != NULL) {
-               /* Seems like our CreateProcess does not work as the windows one.
-                * This hack is needed to deal with paths containing spaces */
-               if (*cmd) {
-                       cmd_utf8 = mono_string_to_utf8_checked (*cmd, &mono_error);
-                       if (!mono_error_set_pending_exception (&mono_error)) {
-                               new_cmd = g_strdup_printf ("%s %s", spath, cmd_utf8);
-                               *cmd = mono_string_new_wrapper (new_cmd);
-                               g_free (cmd_utf8);
-                               g_free (new_cmd);
-                       } else {
-                               *cmd = NULL;
-                       }
-               }
-               else {
-                       *cmd = mono_string_new_wrapper (spath);
-               }
-
-               g_free (spath);
-       }
-
-       return (*cmd != NULL) ? TRUE : FALSE;
-}
-#endif /* HOST_WIN32 */
diff --git a/mono/metadata/process.c b/mono/metadata/process.c
deleted file mode 100644 (file)
index b1bff0b..0000000
+++ /dev/null
@@ -1,921 +0,0 @@
-/*
- * process.c: System.Diagnostics.Process support
- *
- * Author:
- *     Dick Porter (dick@ximian.com)
- *
- * Copyright 2002 Ximian, Inc.
- * Copyright 2002-2006 Novell, Inc.
- * Licensed under the MIT license. See LICENSE file in the project root for full license information.
- */
-
-#include <config.h>
-
-#include <glib.h>
-#include <string.h>
-
-#include <mono/metadata/object-internals.h>
-#include <mono/metadata/process.h>
-#include <mono/metadata/process-internals.h>
-#include <mono/metadata/assembly.h>
-#include <mono/metadata/appdomain.h>
-#include <mono/metadata/image.h>
-#include <mono/metadata/cil-coff.h>
-#include <mono/metadata/exception.h>
-#include <mono/metadata/threadpool-ms-io.h>
-#include <mono/utils/strenc.h>
-#include <mono/utils/mono-proclib.h>
-#include <mono/io-layer/io-layer.h>
-/* FIXME: fix this code to not depend so much on the internals */
-#include <mono/metadata/class-internals.h>
-#include <mono/utils/w32handle.h>
-
-#define LOGDEBUG(...)  
-/* define LOGDEBUG(...) g_message(__VA_ARGS__)  */
-
-#if defined(HOST_WIN32) && G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
-#include <shellapi.h>
-#endif
-
-#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
-HANDLE
-ves_icall_System_Diagnostics_Process_GetProcess_internal (guint32 pid)
-{
-       HANDLE handle;
-       
-       /* GetCurrentProcess returns a pseudo-handle, so use
-        * OpenProcess instead
-        */
-       handle = OpenProcess (PROCESS_ALL_ACCESS, TRUE, pid);
-       if (handle == NULL)
-               /* FIXME: Throw an exception */
-               return NULL;
-       return handle;
-}
-#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT) */
-
-static MonoImage *system_assembly;
-
-static void
-stash_system_assembly (MonoObject *obj)
-{
-       if (!system_assembly)
-               system_assembly = obj->vtable->klass->image;
-}
-
-//Hand coded version that loads from system
-static MonoClass*
-mono_class_get_file_version_info_class (void)
-{
-       static MonoClass *tmp_class;
-       MonoClass *klass = tmp_class;
-       if (!klass) {
-               klass = mono_class_load_from_name (system_assembly, "System.Diagnostics", "FileVersionInfo");
-               mono_memory_barrier ();
-               tmp_class = klass;
-       }
-       return klass;
-}
-
-static MonoClass*
-mono_class_get_process_module_class (void)
-{
-       static MonoClass *tmp_class;
-       MonoClass *klass = tmp_class;
-       if (!klass) {
-               klass = mono_class_load_from_name (system_assembly, "System.Diagnostics", "ProcessModule");
-               mono_memory_barrier ();
-               tmp_class = klass;
-       }
-       return klass;
-}
-
-static guint32
-unicode_chars (const gunichar2 *str)
-{
-       guint32 len;
-
-       for (len = 0; str [len] != '\0'; ++len)
-               ;
-       return len;
-}
-
-static void
-process_set_field_object (MonoObject *obj, const gchar *fieldname,
-                                                 MonoObject *data)
-{
-       MonoClassField *field;
-
-       LOGDEBUG (g_message ("%s: Setting field %s to object at %p", __func__, fieldname, data));
-
-       field = mono_class_get_field_from_name (mono_object_class (obj),
-                                                                                       fieldname);
-       mono_gc_wbarrier_generic_store (((char *)obj) + field->offset, data);
-}
-
-static void
-process_set_field_string (MonoObject *obj, const gchar *fieldname,
-                                                 const gunichar2 *val, guint32 len, MonoError *error)
-{
-       MonoClassField *field;
-       MonoString *string;
-
-       mono_error_init (error);
-
-       LOGDEBUG (g_message ("%s: Setting field %s to [%s]", __func__, fieldname, g_utf16_to_utf8 (val, len, NULL, NULL, NULL)));
-
-       string = mono_string_new_utf16_checked (mono_object_domain (obj), val, len, error);
-       
-       field = mono_class_get_field_from_name (mono_object_class (obj),
-                                                                                       fieldname);
-       mono_gc_wbarrier_generic_store (((char *)obj) + field->offset, (MonoObject*)string);
-}
-
-static void
-process_set_field_string_char (MonoObject *obj, const gchar *fieldname,
-                                                          const gchar *val)
-{
-       MonoClassField *field;
-       MonoString *string;
-
-       LOGDEBUG (g_message ("%s: Setting field %s to [%s]", __func__, fieldname, val));
-
-       string = mono_string_new (mono_object_domain (obj), val);
-       
-       field = mono_class_get_field_from_name (mono_object_class (obj), fieldname);
-       mono_gc_wbarrier_generic_store (((char *)obj) + field->offset, (MonoObject*)string);
-}
-
-static void
-process_set_field_int (MonoObject *obj, const gchar *fieldname,
-                                          guint32 val)
-{
-       MonoClassField *field;
-
-       LOGDEBUG (g_message ("%s: Setting field %s to %d", __func__,fieldname, val));
-       
-       field = mono_class_get_field_from_name (mono_object_class (obj),
-                                             fieldname);
-       *(guint32 *)(((char *)obj) + field->offset)=val;
-}
-
-static void
-process_set_field_intptr (MonoObject *obj, const gchar *fieldname,
-                                                 gpointer val)
-{
-       MonoClassField *field;
-
-       LOGDEBUG (g_message ("%s: Setting field %s to %p", __func__, fieldname, val));
-       
-       field = mono_class_get_field_from_name (mono_object_class (obj),
-                                                                                       fieldname);
-       *(gpointer *)(((char *)obj) + field->offset) = val;
-}
-
-static void
-process_set_field_bool (MonoObject *obj, const gchar *fieldname,
-                                               gboolean val)
-{
-       MonoClassField *field;
-
-       LOGDEBUG (g_message ("%s: Setting field %s to %s", __func__, fieldname, val ? "TRUE":"FALSE"));
-       
-       field = mono_class_get_field_from_name (mono_object_class (obj),
-                                                                                       fieldname);
-       *(guint8 *)(((char *)obj) + field->offset) = val;
-}
-
-#define SFI_COMMENTS           "\\StringFileInfo\\%02X%02X%02X%02X\\Comments"
-#define SFI_COMPANYNAME                "\\StringFileInfo\\%02X%02X%02X%02X\\CompanyName"
-#define SFI_FILEDESCRIPTION    "\\StringFileInfo\\%02X%02X%02X%02X\\FileDescription"
-#define SFI_FILEVERSION                "\\StringFileInfo\\%02X%02X%02X%02X\\FileVersion"
-#define SFI_INTERNALNAME       "\\StringFileInfo\\%02X%02X%02X%02X\\InternalName"
-#define SFI_LEGALCOPYRIGHT     "\\StringFileInfo\\%02X%02X%02X%02X\\LegalCopyright"
-#define SFI_LEGALTRADEMARKS    "\\StringFileInfo\\%02X%02X%02X%02X\\LegalTrademarks"
-#define SFI_ORIGINALFILENAME   "\\StringFileInfo\\%02X%02X%02X%02X\\OriginalFilename"
-#define SFI_PRIVATEBUILD       "\\StringFileInfo\\%02X%02X%02X%02X\\PrivateBuild"
-#define SFI_PRODUCTNAME                "\\StringFileInfo\\%02X%02X%02X%02X\\ProductName"
-#define SFI_PRODUCTVERSION     "\\StringFileInfo\\%02X%02X%02X%02X\\ProductVersion"
-#define SFI_SPECIALBUILD       "\\StringFileInfo\\%02X%02X%02X%02X\\SpecialBuild"
-#define EMPTY_STRING           (gunichar2*)"\000\000"
-
-#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
-static void
-process_module_string_read (MonoObject *filever, gpointer data,
-                           const gchar *fieldname, guchar lang_hi, guchar lang_lo,
-                           const gchar *key, MonoError *error)
-{
-       gchar *lang_key_utf8;
-       gunichar2 *lang_key, *buffer;
-       UINT chars;
-
-       mono_error_init (error);
-
-       lang_key_utf8 = g_strdup_printf (key, lang_lo, lang_hi, 0x04, 0xb0);
-
-       LOGDEBUG (g_message ("%s: asking for [%s]", __func__, lang_key_utf8));
-
-       lang_key = g_utf8_to_utf16 (lang_key_utf8, -1, NULL, NULL, NULL);
-
-       if (VerQueryValue (data, lang_key, (gpointer *)&buffer, &chars) && chars > 0) {
-               LOGDEBUG (g_message ("%s: found %d chars of [%s]", __func__, chars, g_utf16_to_utf8 (buffer, chars, NULL, NULL, NULL)));
-               /* chars includes trailing null */
-               process_set_field_string (filever, fieldname, buffer, chars - 1, error);
-       } else {
-               process_set_field_string (filever, fieldname, EMPTY_STRING, 0, error);
-       }
-
-       g_free (lang_key);
-       g_free (lang_key_utf8);
-}
-
-typedef struct {
-       const char *name;
-       const char *id;
-} StringTableEntry;
-
-static StringTableEntry stringtable_entries [] = {
-       { "comments", SFI_COMMENTS },
-       { "companyname", SFI_COMPANYNAME },
-       { "filedescription", SFI_FILEDESCRIPTION },
-       { "fileversion", SFI_FILEVERSION },
-       { "internalname", SFI_INTERNALNAME },
-       { "legalcopyright", SFI_LEGALCOPYRIGHT },
-       { "legaltrademarks", SFI_LEGALTRADEMARKS },
-       { "originalfilename", SFI_ORIGINALFILENAME },
-       { "privatebuild", SFI_PRIVATEBUILD },
-       { "productname", SFI_PRODUCTNAME },
-       { "productversion", SFI_PRODUCTVERSION },
-       { "specialbuild", SFI_SPECIALBUILD }
-};
-
-static void
-process_module_stringtable (MonoObject *filever, gpointer data,
-                                                       guchar lang_hi, guchar lang_lo, MonoError *error)
-{
-       int i;
-
-       for (i = 0; i < G_N_ELEMENTS (stringtable_entries); ++i) {
-               process_module_string_read (filever, data, stringtable_entries [i].name, lang_hi, lang_lo,
-                                                                       stringtable_entries [i].id, error);
-               return_if_nok (error);
-       }
-}
-
-static void
-process_get_fileversion (MonoObject *filever, gunichar2 *filename, MonoError *error)
-{
-       DWORD verinfohandle;
-       VS_FIXEDFILEINFO *ffi;
-       gpointer data;
-       DWORD datalen;
-       guchar *trans_data;
-       gunichar2 *query;
-       UINT ffi_size, trans_size;
-       BOOL ok;
-       gunichar2 lang_buf[128];
-       guint32 lang, lang_count;
-
-       mono_error_init (error);
-
-       datalen = GetFileVersionInfoSize (filename, &verinfohandle);
-       if (datalen) {
-               data = g_malloc0 (datalen);
-               ok = GetFileVersionInfo (filename, verinfohandle, datalen,
-                                        data);
-               if (ok) {
-                       query = g_utf8_to_utf16 ("\\", -1, NULL, NULL, NULL);
-                       if (query == NULL) {
-                               g_free (data);
-                               return;
-                       }
-                       
-                       if (VerQueryValue (data, query, (gpointer *)&ffi,
-                           &ffi_size)) {
-                               LOGDEBUG (g_message ("%s: recording assembly: FileName [%s] FileVersionInfo [%d.%d.%d.%d]", __func__, g_utf16_to_utf8 (filename, -1, NULL, NULL, NULL), HIWORD (ffi->dwFileVersionMS), LOWORD (ffi->dwFileVersionMS), HIWORD (ffi->dwFileVersionLS), LOWORD (ffi->dwFileVersionLS)));
-       
-                               process_set_field_int (filever, "filemajorpart", HIWORD (ffi->dwFileVersionMS));
-                               process_set_field_int (filever, "fileminorpart", LOWORD (ffi->dwFileVersionMS));
-                               process_set_field_int (filever, "filebuildpart", HIWORD (ffi->dwFileVersionLS));
-                               process_set_field_int (filever, "fileprivatepart", LOWORD (ffi->dwFileVersionLS));
-
-                               process_set_field_int (filever, "productmajorpart", HIWORD (ffi->dwProductVersionMS));
-                               process_set_field_int (filever, "productminorpart", LOWORD (ffi->dwProductVersionMS));
-                               process_set_field_int (filever, "productbuildpart", HIWORD (ffi->dwProductVersionLS));
-                               process_set_field_int (filever, "productprivatepart", LOWORD (ffi->dwProductVersionLS));
-
-                               process_set_field_bool (filever, "isdebug", ((ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_DEBUG) != 0);
-                               process_set_field_bool (filever, "isprerelease", ((ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_PRERELEASE) != 0);
-                               process_set_field_bool (filever, "ispatched", ((ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_PATCHED) != 0);
-                               process_set_field_bool (filever, "isprivatebuild", ((ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_PRIVATEBUILD) != 0);
-                               process_set_field_bool (filever, "isspecialbuild", ((ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_SPECIALBUILD) != 0);
-                       }
-                       g_free (query);
-
-                       query = g_utf8_to_utf16 ("\\VarFileInfo\\Translation", -1, NULL, NULL, NULL);
-                       if (query == NULL) {
-                               g_free (data);
-                               return;
-                       }
-                       
-                       if (VerQueryValue (data, query,
-                                          (gpointer *)&trans_data,
-                                          &trans_size)) {
-                               /* use the first language ID we see
-                                */
-                               if (trans_size >= 4) {
-                                       LOGDEBUG (g_message("%s: %s has 0x%0x 0x%0x 0x%0x 0x%0x", __func__, g_utf16_to_utf8 (filename, -1, NULL, NULL, NULL), trans_data[0], trans_data[1], trans_data[2], trans_data[3]));
-                                       lang = (trans_data[0]) |
-                                               (trans_data[1] << 8) |
-                                               (trans_data[2] << 16) |
-                                               (trans_data[3] << 24);
-                                       /* Only give the lower 16 bits
-                                        * to VerLanguageName, as
-                                        * Windows gets confused
-                                        * otherwise
-                                        */
-                                       lang_count = VerLanguageName (lang & 0xFFFF, lang_buf, 128);
-                                       if (lang_count) {
-                                               process_set_field_string (filever, "language", lang_buf, lang_count, error);
-                                               return_if_nok (error);
-                                       }
-                                       process_module_stringtable (filever, data, trans_data[0], trans_data[1], error);
-                                       return_if_nok (error);
-                               }
-                       } else {
-                               int i;
-
-                               for (i = 0; i < G_N_ELEMENTS (stringtable_entries); ++i) {
-                                       /* No strings, so set every field to
-                                        * the empty string
-                                        */
-                                       process_set_field_string (filever,
-                                                                                         stringtable_entries [i].name,
-                                                                                         EMPTY_STRING, 0, error);
-                                       return_if_nok (error);
-                               }
-
-                               /* And language seems to be set to
-                                * en_US according to bug 374600
-                                */
-                               lang_count = VerLanguageName (0x0409, lang_buf, 128);
-                               if (lang_count) {
-                                       process_set_field_string (filever, "language", lang_buf, lang_count, error);
-                                       return_if_nok (error);
-                               }
-                       }
-                       
-                       g_free (query);
-               }
-               g_free (data);
-       }
-}
-#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
-
-static void
-process_get_assembly_fileversion (MonoObject *filever, MonoAssembly *assembly)
-{
-       process_set_field_int (filever, "filemajorpart", assembly->aname.major);
-       process_set_field_int (filever, "fileminorpart", assembly->aname.minor);
-       process_set_field_int (filever, "filebuildpart", assembly->aname.build);
-}
-
-static MonoObject*
-get_process_module (MonoAssembly *assembly, MonoClass *proc_class, MonoError *error)
-{
-       MonoObject *item, *filever;
-       MonoDomain *domain = mono_domain_get ();
-       char *filename;
-       const char *modulename = assembly->aname.name;
-
-       mono_error_init (error);
-
-       /* Build a System.Diagnostics.ProcessModule with the data.
-        */
-       item = mono_object_new_checked (domain, proc_class, error);
-       return_val_if_nok (error, NULL);
-       filever = mono_object_new_checked (domain, mono_class_get_file_version_info_class (), error);
-       return_val_if_nok (error, NULL);
-
-       filename = g_strdup_printf ("[In Memory] %s", modulename);
-
-       process_get_assembly_fileversion (filever, assembly);
-       process_set_field_string_char (filever, "filename", filename);
-       process_set_field_object (item, "version_info", filever);
-
-       process_set_field_intptr (item, "baseaddr", assembly->image->raw_data);
-       process_set_field_int (item, "memory_size", assembly->image->raw_data_len);
-       process_set_field_string_char (item, "filename", filename);
-       process_set_field_string_char (item, "modulename", modulename);
-
-       g_free (filename);
-
-       return item;
-}
-
-#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
-static MonoObject*
-process_add_module (HANDLE process, HMODULE mod, gunichar2 *filename, gunichar2 *modulename, MonoClass *proc_class, MonoError *error)
-{
-       MonoObject *item, *filever;
-       MonoDomain *domain = mono_domain_get ();
-       MODULEINFO modinfo;
-       BOOL ok;
-
-       mono_error_init (error);
-
-       /* Build a System.Diagnostics.ProcessModule with the data.
-        */
-       item = mono_object_new_checked (domain, proc_class, error);
-       return_val_if_nok (error, NULL);
-       filever = mono_object_new_checked (domain, mono_class_get_file_version_info_class (), error);
-       return_val_if_nok (error, NULL);
-
-       process_get_fileversion (filever, filename, error);
-       return_val_if_nok (error, NULL);
-
-       process_set_field_string (filever, "filename", filename,
-                                                         unicode_chars (filename), error);
-       return_val_if_nok (error, NULL);
-       ok = GetModuleInformation (process, mod, &modinfo, sizeof(MODULEINFO));
-       if (ok) {
-               process_set_field_intptr (item, "baseaddr",
-                                         modinfo.lpBaseOfDll);
-               process_set_field_intptr (item, "entryaddr",
-                                         modinfo.EntryPoint);
-               process_set_field_int (item, "memory_size",
-                                      modinfo.SizeOfImage);
-       }
-       process_set_field_string (item, "filename", filename,
-                                                         unicode_chars (filename), error);
-       return_val_if_nok (error, NULL);
-       process_set_field_string (item, "modulename", modulename,
-                                                         unicode_chars (modulename), error);
-       return_val_if_nok (error, NULL);
-       process_set_field_object (item, "version_info", filever);
-
-       return item;
-}
-#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
-
-static GPtrArray*
-get_domain_assemblies (MonoDomain *domain)
-{
-       GSList *tmp;
-       GPtrArray *assemblies;
-
-       /* 
-        * Make a copy of the list of assemblies because we can't hold the assemblies
-        * lock while creating objects etc.
-        */
-       assemblies = g_ptr_array_new ();
-       mono_domain_assemblies_lock (domain);
-       for (tmp = domain->domain_assemblies; tmp; tmp = tmp->next) {
-               MonoAssembly *ass = (MonoAssembly *)tmp->data;
-               if (ass->image->fileio_used)
-                       continue;
-               g_ptr_array_add (assemblies, ass);
-       }
-       mono_domain_assemblies_unlock (domain);
-
-       return assemblies;
-}
-
-/* Returns an array of System.Diagnostics.ProcessModule */
-#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
-MonoArray *
-ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObject *this_obj, HANDLE process)
-{
-       MonoError error;
-       MonoArray *temp_arr = NULL;
-       MonoArray *arr;
-       HMODULE mods[1024];
-       gunichar2 filename[MAX_PATH];
-       gunichar2 modname[MAX_PATH];
-       DWORD needed;
-       guint32 count = 0, module_count = 0, assembly_count = 0;
-       guint32 i, num_added = 0;
-       GPtrArray *assemblies = NULL;
-
-       stash_system_assembly (this_obj);
-
-       if (GetProcessId (process) == mono_process_current_pid ()) {
-               assemblies = get_domain_assemblies (mono_domain_get ());
-               assembly_count = assemblies->len;
-       }
-
-       if (EnumProcessModules (process, mods, sizeof(mods), &needed)) {
-               module_count += needed / sizeof(HMODULE);
-       }
-
-       count = module_count + assembly_count; 
-       temp_arr = mono_array_new_checked (mono_domain_get (), mono_class_get_process_module_class (), count, &error);
-       if (mono_error_set_pending_exception (&error))
-               return NULL;
-
-       for (i = 0; i < module_count; i++) {
-               if (GetModuleBaseName (process, mods[i], modname, MAX_PATH) &&
-                               GetModuleFileNameEx (process, mods[i], filename, MAX_PATH)) {
-                       MonoObject *module = process_add_module (process, mods[i],
-                                                                                                        filename, modname, mono_class_get_process_module_class (), &error);
-                       if (!mono_error_ok (&error)) {
-                               mono_error_set_pending_exception (&error);
-                               return NULL;
-                       }
-                       mono_array_setref (temp_arr, num_added++, module);
-               }
-       }
-
-       if (assemblies) {
-               for (i = 0; i < assembly_count; i++) {
-                       MonoAssembly *ass = (MonoAssembly *)g_ptr_array_index (assemblies, i);
-                       MonoObject *module = get_process_module (ass, mono_class_get_process_module_class (), &error);
-                       if (!mono_error_ok (&error)) {
-                               mono_error_set_pending_exception (&error);
-                               return NULL;
-                       }
-                       mono_array_setref (temp_arr, num_added++, module);
-               }
-               g_ptr_array_free (assemblies, TRUE);
-       }
-
-       if (count == num_added) {
-               arr = temp_arr;
-       } else {
-               /* shorter version of the array */
-               arr = mono_array_new_checked (mono_domain_get (), mono_class_get_process_module_class (), num_added, &error);
-               if (mono_error_set_pending_exception (&error))
-                       return NULL;
-
-               for (i = 0; i < num_added; i++)
-                       mono_array_setref (arr, i, mono_array_get (temp_arr, MonoObject*, i));
-       }
-
-       return arr;
-}
-#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
-
-void
-ves_icall_System_Diagnostics_FileVersionInfo_GetVersionInfo_internal (MonoObject *this_obj, MonoString *filename)
-{
-       MonoError error;
-
-       stash_system_assembly (this_obj);
-       
-       process_get_fileversion (this_obj, mono_string_chars (filename), &error);
-       if (!mono_error_ok (&error)) {
-               mono_error_set_pending_exception (&error);
-               return;
-       }
-       process_set_field_string (this_obj, "filename",
-                                                         mono_string_chars (filename),
-                                                         mono_string_length (filename), &error);
-       if (!mono_error_ok (&error)) {
-               mono_error_set_pending_exception (&error);
-               return;
-       }
-}
-
-/* Only used when UseShellExecute is false */
-#ifndef HOST_WIN32
-static inline gchar *
-mono_process_quote_path (const gchar *path)
-{
-       return g_shell_quote (path);
-}
-
-static inline gchar *
-mono_process_unquote_application_name (gchar *path)
-{
-       return path;
-}
-#endif /* !HOST_WIN32 */
-
-/* Only used when UseShellExecute is false */
-gboolean
-mono_process_complete_path (const gunichar2 *appname, gchar **completed)
-{
-       gchar *utf8app, *utf8appmemory;
-       gchar *found;
-
-       utf8appmemory = g_utf16_to_utf8 (appname, -1, NULL, NULL, NULL);
-       utf8app = mono_process_unquote_application_name (utf8appmemory);
-
-       if (g_path_is_absolute (utf8app)) {
-               *completed = mono_process_quote_path (utf8app);
-               g_free (utf8appmemory);
-               return TRUE;
-       }
-
-       if (g_file_test (utf8app, G_FILE_TEST_IS_EXECUTABLE) && !g_file_test (utf8app, G_FILE_TEST_IS_DIR)) {
-               *completed = mono_process_quote_path (utf8app);
-               g_free (utf8appmemory);
-               return TRUE;
-       }
-       
-       found = g_find_program_in_path (utf8app);
-       if (found == NULL) {
-               *completed = NULL;
-               g_free (utf8appmemory);
-               return FALSE;
-       }
-
-       *completed = mono_process_quote_path (found);
-       g_free (found);
-       g_free (utf8appmemory);
-       return TRUE;
-}
-
-#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
-MonoBoolean
-ves_icall_System_Diagnostics_Process_ShellExecuteEx_internal (MonoProcessStartInfo *proc_start_info, MonoProcInfo *process_info)
-{
-       SHELLEXECUTEINFO shellex = {0};
-       gboolean ret;
-
-       shellex.cbSize = sizeof(SHELLEXECUTEINFO);
-       shellex.fMask = (gulong)(SEE_MASK_FLAG_DDEWAIT | SEE_MASK_NOCLOSEPROCESS | SEE_MASK_UNICODE);
-       shellex.nShow = (gulong)proc_start_info->window_style;
-       shellex.nShow = (gulong)((shellex.nShow == 0) ? 1 : (shellex.nShow == 1 ? 0 : shellex.nShow));
-
-       if (proc_start_info->filename != NULL) {
-               shellex.lpFile = mono_string_chars (proc_start_info->filename);
-       }
-
-       if (proc_start_info->arguments != NULL) {
-               shellex.lpParameters = mono_string_chars (proc_start_info->arguments);
-       }
-
-       if (proc_start_info->verb != NULL &&
-           mono_string_length (proc_start_info->verb) != 0) {
-               shellex.lpVerb = mono_string_chars (proc_start_info->verb);
-       }
-
-       if (proc_start_info->working_directory != NULL &&
-           mono_string_length (proc_start_info->working_directory) != 0) {
-               shellex.lpDirectory = mono_string_chars (proc_start_info->working_directory);
-       }
-
-       if (proc_start_info->error_dialog) {    
-               shellex.hwnd = proc_start_info->error_dialog_parent_handle;
-       } else {
-               shellex.fMask = (gulong)(shellex.fMask | SEE_MASK_FLAG_NO_UI);
-       }
-
-       ret = ShellExecuteEx (&shellex);
-       if (ret == FALSE) {
-               process_info->pid = -GetLastError ();
-       } else {
-               process_info->process_handle = shellex.hProcess;
-               process_info->thread_handle = NULL;
-#if !defined(MONO_CROSS_COMPILE)
-               process_info->pid = GetProcessId (shellex.hProcess);
-#else
-               process_info->pid = 0;
-#endif
-               process_info->tid = 0;
-       }
-
-       return ret;
-}
-#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
-
-#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
-static inline void
-mono_process_init_startup_info (HANDLE stdin_handle, HANDLE stdout_handle, HANDLE stderr_handle, STARTUPINFO *startinfo)
-{
-       startinfo->cb = sizeof(STARTUPINFO);
-       startinfo->dwFlags = STARTF_USESTDHANDLES;
-       startinfo->hStdInput = stdin_handle;
-       startinfo->hStdOutput = stdout_handle;
-       startinfo->hStdError = stderr_handle;
-       return;
-}
-#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
-
-#ifndef HOST_WIN32
-static gboolean
-mono_process_get_shell_arguments (MonoProcessStartInfo *proc_start_info, gunichar2 **shell_path, MonoString **cmd)
-{
-       gchar *spath = NULL;
-
-       *shell_path = NULL;
-       *cmd = proc_start_info->arguments;
-
-       mono_process_complete_path (mono_string_chars (proc_start_info->filename), &spath);
-       if (spath != NULL) {
-               *shell_path = g_utf8_to_utf16 (spath, -1, NULL, NULL, NULL);
-               g_free (spath);
-       }
-
-       return (*shell_path != NULL) ? TRUE : FALSE;
-}
-#endif /* !HOST_WIN32 */
-
-#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
-static gboolean
-mono_process_create_process (MonoProcInfo *mono_process_info, gunichar2 *shell_path,
-                            MonoString *cmd, guint32 creation_flags, gchar *env_vars,
-                            gunichar2 *dir, STARTUPINFO *start_info, PROCESS_INFORMATION *process_info)
-{
-       gboolean result = FALSE;
-
-       if (mono_process_info->username) {
-               guint32 logon_flags = mono_process_info->load_user_profile ? LOGON_WITH_PROFILE : 0;
-
-               result = CreateProcessWithLogonW (mono_string_chars (mono_process_info->username),
-                                                 mono_process_info->domain ? mono_string_chars (mono_process_info->domain) : NULL,
-                                                 (const gunichar2 *)mono_process_info->password,
-                                                 logon_flags,
-                                                 shell_path,
-                                                 cmd ? mono_string_chars (cmd) : NULL,
-                                                 creation_flags,
-                                                 env_vars, dir, start_info, process_info);
-
-       } else {
-
-               result = CreateProcess (shell_path,
-                                       cmd ? mono_string_chars (cmd): NULL,
-                                       NULL,
-                                       NULL,
-                                       TRUE,
-                                       creation_flags,
-                                       env_vars,
-                                       dir,
-                                       start_info,
-                                       process_info);
-
-       }
-
-       return result;
-}
-#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
-
-MonoBoolean
-ves_icall_System_Diagnostics_Process_CreateProcess_internal (MonoProcessStartInfo *proc_start_info, HANDLE stdin_handle,
-                                                            HANDLE stdout_handle, HANDLE stderr_handle, MonoProcInfo *process_info)
-{
-       gboolean ret;
-       gunichar2 *dir;
-       STARTUPINFO startinfo={0};
-       PROCESS_INFORMATION procinfo;
-       gunichar2 *shell_path = NULL;
-       gchar *env_vars = NULL;
-       MonoString *cmd = NULL;
-       guint32 creation_flags;
-
-       mono_process_init_startup_info (stdin_handle, stdout_handle, stderr_handle, &startinfo);
-
-       creation_flags = CREATE_UNICODE_ENVIRONMENT;
-       if (proc_start_info->create_no_window)
-               creation_flags |= CREATE_NO_WINDOW;
-       
-       if (mono_process_get_shell_arguments (proc_start_info, &shell_path, &cmd) == FALSE) {
-               process_info->pid = -ERROR_FILE_NOT_FOUND;
-               return FALSE;
-       }
-
-       if (process_info->env_keys) {
-               gint i, len; 
-               MonoString *ms;
-               MonoString *key, *value;
-               gunichar2 *str, *ptr;
-               gunichar2 *equals16;
-
-               for (len = 0, i = 0; i < mono_array_length (process_info->env_keys); i++) {
-                       ms = mono_array_get (process_info->env_values, MonoString *, i);
-                       if (ms == NULL)
-                               continue;
-
-                       len += mono_string_length (ms) * sizeof (gunichar2);
-                       ms = mono_array_get (process_info->env_keys, MonoString *, i);
-                       len += mono_string_length (ms) * sizeof (gunichar2);
-                       len += 2 * sizeof (gunichar2);
-               }
-
-               equals16 = g_utf8_to_utf16 ("=", 1, NULL, NULL, NULL);
-               ptr = str = g_new0 (gunichar2, len + 1);
-               for (i = 0; i < mono_array_length (process_info->env_keys); i++) {
-                       value = mono_array_get (process_info->env_values, MonoString *, i);
-                       if (value == NULL)
-                               continue;
-
-                       key = mono_array_get (process_info->env_keys, MonoString *, i);
-                       memcpy (ptr, mono_string_chars (key), mono_string_length (key) * sizeof (gunichar2));
-                       ptr += mono_string_length (key);
-
-                       memcpy (ptr, equals16, sizeof (gunichar2));
-                       ptr++;
-
-                       memcpy (ptr, mono_string_chars (value), mono_string_length (value) * sizeof (gunichar2));
-                       ptr += mono_string_length (value);
-                       ptr++;
-               }
-
-               g_free (equals16);
-               env_vars = (gchar *) str;
-       }
-       
-       /* The default dir name is "".  Turn that into NULL to mean
-        * "current directory"
-        */
-       if (proc_start_info->working_directory == NULL || mono_string_length (proc_start_info->working_directory) == 0)
-               dir = NULL;
-       else
-               dir = mono_string_chars (proc_start_info->working_directory);
-
-       ret = mono_process_create_process (process_info, shell_path, cmd, creation_flags, env_vars, dir, &startinfo, &procinfo);
-
-       g_free (env_vars);
-       if (shell_path != NULL)
-               g_free (shell_path);
-
-       if (ret) {
-               process_info->process_handle = procinfo.hProcess;
-               /*process_info->thread_handle=procinfo.hThread;*/
-               process_info->thread_handle = NULL;
-               if (procinfo.hThread != NULL && procinfo.hThread != INVALID_HANDLE_VALUE)
-                       CloseHandle (procinfo.hThread);
-               process_info->pid = procinfo.dwProcessId;
-               process_info->tid = procinfo.dwThreadId;
-       } else {
-               process_info->pid = -GetLastError ();
-       }
-       
-       return ret;
-}
-
-#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
-MonoString *
-ves_icall_System_Diagnostics_Process_ProcessName_internal (HANDLE process)
-{
-       MonoError error;
-       MonoString *string;
-       gunichar2 name[MAX_PATH];
-       guint32 len;
-       gboolean ok;
-       HMODULE mod;
-       DWORD needed;
-
-       ok = EnumProcessModules (process, &mod, sizeof(mod), &needed);
-       if (!ok)
-               return NULL;
-       
-       len = GetModuleBaseName (process, mod, name, MAX_PATH);
-
-       if (len == 0)
-               return NULL;
-       
-       LOGDEBUG (g_message ("%s: process name is [%s]", __func__, g_utf16_to_utf8 (name, -1, NULL, NULL, NULL)));
-       
-       string = mono_string_new_utf16_checked (mono_domain_get (), name, len, &error);
-       if (!mono_error_ok (&error))
-               mono_error_set_pending_exception (&error);
-       
-       return string;
-}
-#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
-
-#ifndef HOST_WIN32
-/* Returns an array of pids */
-MonoArray *
-ves_icall_System_Diagnostics_Process_GetProcesses_internal (void)
-{
-       MonoError error;
-       MonoArray *procs;
-       gpointer *pidarray;
-       int i, count;
-
-       pidarray = mono_process_list (&count);
-       if (!pidarray) {
-               mono_set_pending_exception (mono_get_exception_not_supported ("This system does not support EnumProcesses"));
-               return NULL;
-       }
-       procs = mono_array_new_checked (mono_domain_get (), mono_get_int32_class (), count, &error);
-       if (mono_error_set_pending_exception (&error)) {
-               g_free (pidarray);
-               return NULL;
-       }
-       if (sizeof (guint32) == sizeof (gpointer)) {
-               memcpy (mono_array_addr (procs, guint32, 0), pidarray, count * sizeof (gint32));
-       } else {
-               for (i = 0; i < count; ++i)
-                       *(mono_array_addr (procs, guint32, i)) = GPOINTER_TO_UINT (pidarray [i]);
-       }
-       g_free (pidarray);
-
-       return procs;
-}
-#endif /* !HOST_WIN32 */
-
-gint64
-ves_icall_System_Diagnostics_Process_GetProcessData (int pid, gint32 data_type, gint32 *error)
-{
-       MonoProcessError perror;
-       guint64 res;
-
-       res = mono_process_get_data_with_error (GINT_TO_POINTER (pid), (MonoProcessData)data_type, &perror);
-       if (error)
-               *error = perror;
-       return res;
-}
diff --git a/mono/metadata/process.h b/mono/metadata/process.h
deleted file mode 100644 (file)
index bad2095..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * process.h: System.Diagnostics.Process support
- *
- * Author:
- *     Dick Porter (dick@ximian.com)
- *
- * (C) 2002 Ximian, Inc.
- */
-
-#ifndef _MONO_METADATA_PROCESS_H_
-#define _MONO_METADATA_PROCESS_H_
-
-#include <config.h>
-#include <glib.h>
-
-#include <mono/metadata/object.h>
-#include <mono/io-layer/io-layer.h>
-#include "mono/utils/mono-compiler.h"
-
-typedef struct 
-{
-       HANDLE process_handle;
-       HANDLE thread_handle;
-       guint32 pid; /* Contains GetLastError () on failure */
-       guint32 tid;
-       MonoArray *env_keys;
-       MonoArray *env_values;
-       MonoString *username;
-       MonoString *domain;
-       gpointer password; /* BSTR from SecureString in 2.0 profile */
-       MonoBoolean load_user_profile;
-} MonoProcInfo;
-
-typedef struct
-{
-       MonoObject object;
-       MonoString *filename;
-       MonoString *arguments;
-       MonoString *working_directory;
-       MonoString *verb;
-       guint32 window_style;
-       MonoBoolean error_dialog;
-       gpointer error_dialog_parent_handle;
-       MonoBoolean use_shell_execute;
-       MonoString *username;
-       MonoString *domain;
-       MonoObject *password; /* SecureString in 2.0 profile, dummy in 1.x */
-       MonoString *password_in_clear_text;
-       MonoBoolean load_user_profile;
-       MonoBoolean redirect_standard_input;
-       MonoBoolean redirect_standard_output;
-       MonoBoolean redirect_standard_error;
-       MonoObject *encoding_stdout;
-       MonoObject *encoding_stderr;
-       MonoBoolean create_no_window;
-       MonoObject *weak_parent_process;
-       MonoObject *envVars;
-} MonoProcessStartInfo;
-
-G_BEGIN_DECLS
-
-HANDLE ves_icall_System_Diagnostics_Process_GetProcess_internal (guint32 pid);
-MonoArray *ves_icall_System_Diagnostics_Process_GetProcesses_internal (void);
-MonoArray *ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObject *this_obj, HANDLE process);
-void ves_icall_System_Diagnostics_FileVersionInfo_GetVersionInfo_internal (MonoObject *this_obj, MonoString *filename);
-MonoBoolean ves_icall_System_Diagnostics_Process_ShellExecuteEx_internal (MonoProcessStartInfo *proc_start_info, MonoProcInfo *process_handle);
-MonoBoolean ves_icall_System_Diagnostics_Process_CreateProcess_internal (MonoProcessStartInfo *proc_start_info, HANDLE stdin_handle, HANDLE stdout_handle, HANDLE stderr_handle, MonoProcInfo *process_handle);
-MonoString *ves_icall_System_Diagnostics_Process_ProcessName_internal (HANDLE process);
-gint64 ves_icall_System_Diagnostics_Process_GetProcessData (int pid, gint32 data_type, gint32 *error);
-
-G_END_DECLS
-
-#endif /* _MONO_METADATA_PROCESS_H_ */
-
index 967867149caa4c79eaea873cd615b16ee230bd95..85e757fbf5dbf85904bd7c00fcb4b71347c72e5d 100644 (file)
@@ -41,13 +41,13 @@ MonoArray*
 mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues, MonoError *error);
 
 MonoCustomAttrInfo*
-mono_custom_attrs_from_index_checked    (MonoImage *image, uint32_t idx, MonoError *error);
+mono_custom_attrs_from_index_checked    (MonoImage *image, uint32_t idx, gboolean ignore_missing, MonoError *error);
 MonoCustomAttrInfo*
 mono_custom_attrs_from_method_checked   (MonoMethod *method, MonoError *error);
 MonoCustomAttrInfo*
 mono_custom_attrs_from_class_checked           (MonoClass *klass, MonoError *error);
 MonoCustomAttrInfo*
-mono_custom_attrs_from_assembly_checked        (MonoAssembly *assembly, MonoError *error);
+mono_custom_attrs_from_assembly_checked        (MonoAssembly *assembly, gboolean ignore_missing, MonoError *error);
 MonoCustomAttrInfo*
 mono_custom_attrs_from_property_checked        (MonoClass *klass, MonoProperty *property, MonoError *error);
 MonoCustomAttrInfo*
index e17bf8692087481ac62bb52e93ba94263d8ecd34..88ecb5fddfdf84bb216c4259845dbc865569cf3e 100644 (file)
@@ -46,6 +46,7 @@
 #include <mono/utils/mono-string.h>
 #include <mono/utils/mono-error-internals.h>
 #include <mono/utils/checked-build.h>
+#include <mono/utils/mono-counters.h>
 
 static void get_default_param_value_blobs (MonoMethod *method, char **blobs, guint32 *types);
 static MonoType* mono_reflection_get_type_with_rootimage (MonoImage *rootimage, MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve, MonoError *error);
@@ -66,10 +67,17 @@ static GENERATE_GET_CLASS_WITH_CACHE (exception_handling_clause, System.Reflecti
 static GENERATE_GET_CLASS_WITH_CACHE (type_builder, System.Reflection.Emit, TypeBuilder);
 static GENERATE_GET_CLASS_WITH_CACHE (dbnull, System, DBNull);
 
+
+static int class_ref_info_handle_count;
+
 void
 mono_reflection_init (void)
 {
        mono_reflection_emit_init ();
+
+       mono_counters_register ("MonoClass::ref_info_handle count",
+                                                       MONO_COUNTER_METADATA | MONO_COUNTER_INT, &class_ref_info_handle_count);
+
 }
 
 /*
@@ -94,6 +102,7 @@ mono_class_set_ref_info (MonoClass *klass, gpointer obj)
        MONO_REQ_GC_UNSAFE_MODE;
 
        klass->ref_info_handle = mono_gchandle_new ((MonoObject*)obj, FALSE);
+       ++class_ref_info_handle_count;
        g_assert (klass->ref_info_handle != 0);
 }
 
@@ -343,7 +352,7 @@ mono_type_normalize (MonoType *type)
                return type;
 
        gtd = gclass->container_class;
-       gcontainer = gtd->generic_container;
+       gcontainer = mono_class_get_generic_container (gtd);
        argv = g_newa (MonoType*, ginst->type_argc);
 
        for (i = 0; i < ginst->type_argc; ++i) {
@@ -2147,12 +2156,20 @@ mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc
        }
 
        klass = mono_class_from_mono_type (t);
-       if (!klass->generic_container) {
+       if (!mono_class_is_gtd (klass)) {
                mono_loader_unlock ();
                mono_error_set_type_load_class (error, klass, "Cannot bind generic parameters of a non-generic type");
                return NULL;
        }
 
+       guint gtd_type_argc = mono_class_get_generic_container (klass)->type_argc;
+       if (gtd_type_argc != type_argc) {
+               mono_loader_unlock ();
+               mono_error_set_argument (error, "types", "The generic type definition needs %d type arguments, but was instantiated with %d ", gtd_type_argc, type_argc);
+               return NULL;
+       }
+
+
        if (klass->wastypebuilder)
                is_dynamic = TRUE;
 
@@ -2169,7 +2186,7 @@ mono_class_bind_generic_parameters (MonoClass *klass, int type_argc, MonoType **
        MonoGenericClass *gclass;
        MonoGenericInst *inst;
 
-       g_assert (klass->generic_container);
+       g_assert (mono_class_is_gtd (klass));
 
        inst = mono_metadata_get_generic_inst (type_argc, types);
        gclass = mono_metadata_lookup_generic_class (klass, inst, is_dynamic);
@@ -2215,7 +2232,7 @@ reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, MonoAr
        ginst = mono_metadata_get_generic_inst (count, type_argv);
        g_free (type_argv);
 
-       tmp_context.class_inst = klass->generic_class ? klass->generic_class->context.class_inst : NULL;
+       tmp_context.class_inst = mono_class_is_ginst (klass) ? mono_class_get_generic_class (klass)->context.class_inst : NULL;
        tmp_context.method_inst = ginst;
 
        inflated = mono_class_inflate_generic_method_checked (method, &tmp_context, error);
@@ -2345,7 +2362,7 @@ mono_declsec_flags_from_method (MonoMethod *method)
 guint32
 mono_declsec_flags_from_class (MonoClass *klass)
 {
-       if (klass->flags & TYPE_ATTRIBUTE_HAS_SECURITY) {
+       if (mono_class_get_flags (klass) & TYPE_ATTRIBUTE_HAS_SECURITY) {
                if (!klass->ext || !klass->ext->declsec_flags) {
                        guint32 idx;
 
index b6b594071296138a7fed75f03e6d122a98c82767..4f996c727d73161c972cb8a5af4fcfef55060258 100644 (file)
@@ -450,6 +450,7 @@ mono_seq_point_data_write (SeqPointData *data, char *path)
 
        fwrite (buffer_orig, 1, buffer - buffer_orig, f);
        g_free (buffer_orig);
+       fclose (f);
 
        return TRUE;
 }
index 6372084d21dfb43b801fd1a0374c5aeb12a463c1..26e6a089b5dbb987e5d5cb6af8efc54b7c63eca1 100644 (file)
@@ -212,6 +212,32 @@ sgen_has_critical_method (void)
        return sgen_has_managed_allocator ();
 }
 
+static gboolean
+ip_in_critical_region (MonoDomain *domain, gpointer ip)
+{
+       MonoJitInfo *ji;
+       MonoMethod *method;
+
+       /*
+        * We pass false for 'try_aot' so this becomes async safe.
+        * It won't find aot methods whose jit info is not yet loaded,
+        * so we preload their jit info in the JIT.
+        */
+       ji = mono_jit_info_table_find_internal (domain, ip, FALSE, FALSE);
+       if (!ji)
+               return FALSE;
+
+       method = mono_jit_info_get_method (ji);
+
+       return mono_runtime_is_critical_method (method) || sgen_is_critical_method (method);
+}
+
+gboolean
+mono_gc_is_critical_method (MonoMethod *method)
+{
+       return sgen_is_critical_method (method);
+}
+
 #ifndef DISABLE_JIT
 
 static void
@@ -2285,12 +2311,6 @@ mono_gc_set_skip_thread (gboolean skip)
        UNLOCK_GC;
 }
 
-static gboolean
-is_critical_method (MonoMethod *method)
-{
-       return mono_runtime_is_critical_method (method) || sgen_is_critical_method (method);
-}
-
 static gboolean
 thread_in_critical_region (SgenThreadInfo *info)
 {
@@ -2845,8 +2865,8 @@ sgen_client_init (void)
        cb.thread_detach = sgen_thread_detach;
        cb.thread_unregister = sgen_thread_unregister;
        cb.thread_attach = sgen_thread_attach;
-       cb.mono_method_is_critical = (gboolean (*)(void *))is_critical_method;
        cb.mono_thread_in_critical_region = thread_in_critical_region;
+       cb.ip_in_critical_region = ip_in_critical_region;
 
        mono_threads_init (&cb, sizeof (SgenThreadInfo));
 
index cdfbb64c027bec5dcb8bb4859e9f64d0bcdfd248..8b51ccf588a23f92ff45121dbc1499c5957b5bbc 100644 (file)
@@ -196,7 +196,7 @@ class_kind (MonoClass *klass)
 
                /* FIXME the bridge check can be quite expensive, cache it at the class level. */
                /* An array of a sealed type that is not a bridge will never get to a bridge */
-               if ((elem_class->flags & TYPE_ATTRIBUTE_SEALED) && !elem_class->has_references && !bridge_callbacks.bridge_class_kind (elem_class)) {
+               if ((mono_class_get_flags (elem_class) & TYPE_ATTRIBUTE_SEALED) && !elem_class->has_references && !bridge_callbacks.bridge_class_kind (elem_class)) {
                        SGEN_LOG (6, "class %s is opaque\n", klass->name);
                        return GC_BRIDGE_OPAQUE_CLASS;
                }
index daa983e64ac61ce1a29d534c4f2785d872e5e3ce..fc9a73de67d011c315611e66f02b762b081236ba 100644 (file)
@@ -62,7 +62,7 @@ class_kind (MonoClass *klass)
 
                /* FIXME the bridge check can be quite expensive, cache it at the class level. */
                /* An array of a sealed type that is not a bridge will never get to a bridge */
-               if ((elem_class->flags & TYPE_ATTRIBUTE_SEALED) && !elem_class->has_references && !bridge_callbacks.bridge_class_kind (elem_class)) {
+               if ((mono_class_get_flags (elem_class) & TYPE_ATTRIBUTE_SEALED) && !elem_class->has_references && !bridge_callbacks.bridge_class_kind (elem_class)) {
                        SGEN_LOG (6, "class %s is opaque\n", klass->name);
                        return GC_BRIDGE_OPAQUE_CLASS;
                }
index 2df84e99c8f9658a398e4c089d1155be2e64906a..b5866b73a22bb730dc3109f85cf6c7576e1f7662 100644 (file)
@@ -62,7 +62,7 @@
 #include <mono/utils/mono-threads.h>
 #include <mono/utils/mono-memory-model.h>
 #include <mono/utils/networking.h>
-#include <mono/utils/w32handle.h>
+#include <mono/metadata/w32handle.h>
 
 #include <time.h>
 #ifdef HAVE_SYS_TIME_H
index 1d9e50ba93ce86dd692da0586f8e951df4c590de..a412c1560960f925edd780db02449fefed963aa4 100644 (file)
@@ -195,8 +195,8 @@ encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf)
        case MONO_TYPE_CLASS: {
                MonoClass *k = mono_class_from_mono_type (type);
 
-               if (k->generic_container) {
-                       MonoGenericClass *gclass = mono_metadata_lookup_generic_class (k, k->generic_container->context.class_inst, TRUE);
+               if (mono_class_is_gtd (k)) {
+                       MonoGenericClass *gclass = mono_metadata_lookup_generic_class (k, mono_class_get_generic_container (k)->context.class_inst, TRUE);
                        encode_generic_class (assembly, gclass, buf);
                } else {
                        /*
@@ -571,7 +571,7 @@ handle_enum:
                return idx;
        }
        case MONO_TYPE_GENERICINST:
-               *ret_type = val->vtable->klass->generic_class->container_class->byval_arg.type;
+               *ret_type = mono_class_get_generic_class (val->vtable->klass)->container_class->byval_arg.type;
                goto handle_enum;
        default:
                g_error ("we don't encode constant type 0x%02x yet", *ret_type);
@@ -616,12 +616,12 @@ mono_dynimage_encode_field_signature (MonoDynamicImage *assembly, MonoReflection
                goto fail;
        /* encode custom attributes before the type */
 
-       if (klass->generic_container)
+       if (mono_class_is_gtd (klass))
                typespec = create_typespec (assembly, type);
 
        if (typespec) {
                MonoGenericClass *gclass;
-               gclass = mono_metadata_lookup_generic_class (klass, klass->generic_container->context.class_inst, TRUE);
+               gclass = mono_metadata_lookup_generic_class (klass, mono_class_get_generic_container (klass)->context.class_inst, TRUE);
                encode_generic_class (assembly, gclass, &buf);
        } else {
                encode_type (assembly, type, &buf);
@@ -712,7 +712,7 @@ create_typespec (MonoDynamicImage *assembly, MonoType *type)
        case MONO_TYPE_CLASS:
        case MONO_TYPE_VALUETYPE: {
                MonoClass *k = mono_class_from_mono_type (type);
-               if (!k || !k->generic_container) {
+               if (!k || !mono_class_is_gtd (k)) {
                        sigbuffer_free (&buf);
                        return 0;
                }
@@ -756,8 +756,6 @@ mono_dynimage_encode_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType *
        if (token)
                return token;
        klass = mono_class_from_mono_type (type);
-       if (!klass)
-               klass = mono_class_from_mono_type (type);
 
        /*
         * If it's in the same module and not a generic type parameter:
index 3256f8cb1990d4e3b18a5d2e8e92d668ada6fa08..2f32e315a429ce58d78d7d89f304bc1f491dc5d0 100644 (file)
@@ -1194,7 +1194,7 @@ mono_image_fill_export_table_from_class (MonoDomain *domain, MonoClass *klass,
        guint32 *values;
        guint32 visib, res;
 
-       visib = klass->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK;
+       visib = mono_class_get_flags (klass) & TYPE_ATTRIBUTE_VISIBILITY_MASK;
        if (! ((visib & TYPE_ATTRIBUTE_PUBLIC) || (visib & TYPE_ATTRIBUTE_NESTED_PUBLIC)))
                return 0;
 
@@ -1203,7 +1203,7 @@ mono_image_fill_export_table_from_class (MonoDomain *domain, MonoClass *klass,
        alloc_table (table, table->rows);
        values = table->values + table->next_idx * MONO_EXP_TYPE_SIZE;
 
-       values [MONO_EXP_TYPE_FLAGS] = klass->flags;
+       values [MONO_EXP_TYPE_FLAGS] = mono_class_get_flags (klass);
        values [MONO_EXP_TYPE_TYPEDEF] = klass->type_token;
        if (klass->nested_in)
                values [MONO_EXP_TYPE_IMPLEMENTATION] = (parent_index << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_EXP_TYPE;
@@ -1274,7 +1274,7 @@ mono_image_fill_export_table_from_module (MonoDomain *domain, MonoReflectionModu
                MonoClass *klass = mono_class_get_checked (image, mono_metadata_make_token (MONO_TABLE_TYPEDEF, i + 1), &error);
                g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
 
-               if (klass->flags & TYPE_ATTRIBUTE_PUBLIC)
+               if (mono_class_is_public (klass))
                        mono_image_fill_export_table_from_class (domain, klass, module_index, 0, assembly);
        }
 }
@@ -1743,7 +1743,7 @@ fixup_method (MonoReflectionILGen *ilgen, gpointer value, MonoDynamicImage *asse
                        } else if (!strcmp (iltoken->member->vtable->klass->name, "MonoMethod") ||
                                           !strcmp (iltoken->member->vtable->klass->name, "MonoCMethod")) {
                                MonoMethod *m = ((MonoReflectionMethod*)iltoken->member)->method;
-                               g_assert (m->klass->generic_class || m->klass->generic_container);
+                               g_assert (mono_class_is_ginst (m->klass) || mono_class_is_gtd (m->klass));
                                continue;
                        } else if (!strcmp (iltoken->member->vtable->klass->name, "FieldBuilder")) {
                                g_assert_not_reached ();
index e2ec3395e5cf9ed927389217429717a507e2feda..10a916758df11f2e6d84f09e1f5a80634b3c473a 100644 (file)
@@ -96,7 +96,7 @@ type_get_qualified_name (MonoType *type, MonoAssembly *ass)
                return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
        ta = klass->image->assembly;
        if (assembly_is_dynamic (ta) || (ta == ass)) {
-               if (klass->generic_class || klass->generic_container)
+               if (mono_class_is_ginst (klass) || mono_class_is_gtd (klass))
                        /* For generic type definitions, we want T, while REFLECTION returns T<K> */
                        return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_FULL_NAME);
                else
@@ -704,7 +704,7 @@ mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 origina
 static gboolean
 is_field_on_inst (MonoClassField *field)
 {
-       return field->parent->generic_class && field->parent->generic_class->is_dynamic;
+       return mono_class_is_ginst (field->parent) && mono_class_get_generic_class (field->parent)->is_dynamic;
 }
 
 #ifndef DISABLE_REFLECTION_EMIT
@@ -721,9 +721,9 @@ mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObject *f, MonoCl
        if (token)
                return token;
 
-       if (field->parent->generic_class && field->parent->generic_class->container_class && field->parent->generic_class->container_class->fields) {
+       if (mono_class_is_ginst (field->parent) && mono_class_get_generic_class (field->parent)->container_class && mono_class_get_generic_class (field->parent)->container_class->fields) {
                int index = field - field->parent->fields;
-               type = mono_field_get_type (&field->parent->generic_class->container_class->fields [index]);
+               type = mono_field_get_type (&mono_class_get_generic_class (field->parent)->container_class->fields [index]);
        } else {
                type = mono_field_get_type (field);
        }
@@ -1138,7 +1138,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
                return_val_if_nok (error, 0);
                MonoClass *mc = mono_class_from_mono_type (type);
                token = mono_metadata_token_from_dor (
-                       mono_dynimage_encode_typedef_or_ref_full (assembly, type, mc->generic_container == NULL || create_open_instance));
+                       mono_dynimage_encode_typedef_or_ref_full (assembly, type, !mono_class_is_gtd (mc) || create_open_instance));
        } else if (strcmp (klass->name, "MonoCMethod") == 0 ||
                           strcmp (klass->name, "MonoMethod") == 0) {
                MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
@@ -1148,7 +1148,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
                        else
                                token = mono_image_get_inflated_method_token (assembly, m->method);
                } else if ((m->method->klass->image == &assembly->image) &&
-                        !m->method->klass->generic_class) {
+                        !mono_class_is_ginst (m->method->klass)) {
                        static guint32 method_table_idx = 0xffffff;
                        if (m->method->klass->wastypebuilder) {
                                /* we use the same token as the one that was assigned
@@ -1583,8 +1583,8 @@ mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
                        MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)(gparam->tbuilder), error);
                        mono_error_assert_ok (error);
                        MonoClass *owner = mono_class_from_mono_type (type);
-                       g_assert (owner->generic_container);
-                       param->param.owner = owner->generic_container;
+                       g_assert (mono_class_is_gtd (owner));
+                       param->param.owner = mono_class_get_generic_container (owner);
                }
 
                pklass = mono_class_from_generic_parameter_internal ((MonoGenericParam *) param);
@@ -2298,7 +2298,13 @@ reflection_setup_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error
                return TRUE;
        }
 
-       klass = (MonoClass *)mono_image_alloc0 (&tb->module->dynamic_image->image, sizeof (MonoClass));
+       /*
+        * The size calculation here warrants some explaining. 
+        * reflection_setup_internal_class is called too early, well before we know whether the type will be a GTD or DEF,
+        * meaning we need to alloc enough space to morth a def into a gtd.
+        */
+       klass = (MonoClass *)mono_image_alloc0 (&tb->module->dynamic_image->image, MAX (sizeof (MonoClassDef), sizeof (MonoClassGtd)));
+       klass->class_kind = MONO_CLASS_DEF;
 
        klass->image = &tb->module->dynamic_image->image;
 
@@ -2310,7 +2316,7 @@ reflection_setup_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error
        if (!is_ok (error))
                goto failure;
        klass->type_token = MONO_TOKEN_TYPE_DEF | tb->table_idx;
-       klass->flags = tb->attrs;
+       mono_class_set_flags (klass, tb->attrs);
        
        mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD);
 
@@ -2410,29 +2416,31 @@ reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error
        if (count == 0)
                return TRUE;
 
-       klass->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
+       MonoGenericContainer *generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
+
+       generic_container->owner.klass = klass;
+       generic_container->type_argc = count;
+       generic_container->type_params = (MonoGenericParamFull *)mono_image_alloc0 (klass->image, sizeof (MonoGenericParamFull) * count);
 
-       klass->generic_container->owner.klass = klass;
-       klass->generic_container->type_argc = count;
-       klass->generic_container->type_params = (MonoGenericParamFull *)mono_image_alloc0 (klass->image, sizeof (MonoGenericParamFull) * count);
+       klass->class_kind = MONO_CLASS_GTD;
+       mono_class_set_generic_container (klass, generic_container);
 
-       klass->is_generic = 1;
 
        for (i = 0; i < count; i++) {
                MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)mono_array_get (tb->generic_params, gpointer, i);
                MonoType *param_type = mono_reflection_type_get_handle ((MonoReflectionType*)gparam, error);
                return_val_if_nok (error, FALSE);
                MonoGenericParamFull *param = (MonoGenericParamFull *) param_type->data.generic_param;
-               klass->generic_container->type_params [i] = *param;
+               generic_container->type_params [i] = *param;
                /*Make sure we are a diferent type instance */
-               klass->generic_container->type_params [i].param.owner = klass->generic_container;
-               klass->generic_container->type_params [i].info.pklass = NULL;
-               klass->generic_container->type_params [i].info.flags = gparam->attrs;
+               generic_container->type_params [i].param.owner = generic_container;
+               generic_container->type_params [i].info.pklass = NULL;
+               generic_container->type_params [i].info.flags = gparam->attrs;
 
-               g_assert (klass->generic_container->type_params [i].param.owner);
+               g_assert (generic_container->type_params [i].param.owner);
        }
 
-       klass->generic_container->context.class_inst = mono_get_shared_generic_inst (klass->generic_container);
+       generic_container->context.class_inst = mono_get_shared_generic_inst (generic_container);
        return TRUE;
 }
 
@@ -2573,7 +2581,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
        image = dynamic ? NULL : klass->image;
 
        if (!dynamic)
-               g_assert (!klass->generic_class);
+               g_assert (!mono_class_is_ginst (klass));
 
        mono_loader_lock ();
 
@@ -2724,9 +2732,9 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                        }
                }
 
-               if (klass->generic_container) {
-                       container->parent = klass->generic_container;
-                       container->context.class_inst = klass->generic_container->context.class_inst;
+               if (mono_class_is_gtd (klass)) {
+                       container->parent = mono_class_get_generic_container (klass);
+                       container->context.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
                }
                container->context.method_inst = mono_get_shared_generic_inst (container);
        }
@@ -2903,7 +2911,7 @@ methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilder* mb,
 static gboolean
 fix_partial_generic_class (MonoClass *klass, MonoError *error)
 {
-       MonoClass *gklass = klass->generic_class->container_class;
+       MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
        int i;
 
        mono_error_init (error);
@@ -2912,7 +2920,7 @@ fix_partial_generic_class (MonoClass *klass, MonoError *error)
                return TRUE;
 
        if (klass->parent != gklass->parent) {
-               MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &klass->generic_class->context, error);
+               MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &mono_class_get_generic_class (klass)->context, error);
                if (mono_error_ok (error)) {
                        MonoClass *parent = mono_class_from_mono_type (parent_type);
                        mono_metadata_free_type (parent_type);
@@ -2928,7 +2936,7 @@ fix_partial_generic_class (MonoClass *klass, MonoError *error)
                }
        }
 
-       if (!klass->generic_class->need_sync)
+       if (!mono_class_get_generic_class (klass)->need_sync)
                return TRUE;
 
        if (klass->method.count != gklass->method.count) {
@@ -2989,7 +2997,7 @@ fix_partial_generic_class (MonoClass *klass, MonoError *error)
 static gboolean
 ensure_generic_class_runtime_vtable (MonoClass *klass, MonoError *error)
 {
-       MonoClass *gklass = klass->generic_class->container_class;
+       MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
 
        mono_error_init (error);
 
@@ -3015,7 +3023,7 @@ ensure_runtime_vtable (MonoClass *klass, MonoError *error)
 
        mono_error_init (error);
 
-       if (!image_is_dynamic (klass->image) || (!tb && !klass->generic_class) || klass->wastypebuilder)
+       if (!image_is_dynamic (klass->image) || (!tb && !mono_class_is_ginst (klass)) || klass->wastypebuilder)
                return TRUE;
        if (klass->parent)
                if (!ensure_runtime_vtable (klass->parent, error))
@@ -3054,14 +3062,14 @@ ensure_runtime_vtable (MonoClass *klass, MonoError *error)
                        }
                        klass->interfaces_inited = 1;
                }
-       } else if (klass->generic_class){
+       } else if (mono_class_is_ginst (klass)){
                if (!ensure_generic_class_runtime_vtable (klass, error)) {
                        mono_class_set_type_load_failure (klass, "Could not initialize vtable for generic class due to: %s", mono_error_get_message (error));
                        return FALSE;
                }
        }
 
-       if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
+       if (mono_class_is_interface (klass)) {
                int slot_num = 0;
                for (i = 0; i < klass->method.count; ++i) {
                        MonoMethod *im = klass->methods [i];
@@ -3191,7 +3199,6 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
        }
 
        klass->field.count = tb->num_fields;
-       klass->field.first = 0;
 
        mono_error_init (error);
 
@@ -3216,6 +3223,7 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
                MonoArray *rva_data;
                fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
                field = &klass->fields [i];
+               field->parent = klass;
                field->name = mono_string_to_utf8_image (image, fb->name, error);
                if (!mono_error_ok (error))
                        return;
@@ -3238,7 +3246,6 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
                }
                if (fb->offset != -1)
                        field->offset = fb->offset;
-               field->parent = klass;
                fb->handle = field;
                mono_save_custom_attrs (klass->image, field, fb->cattrs);
 
@@ -3428,7 +3435,7 @@ ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
         * Fields to set in klass:
         * the various flags: delegate/unicode/contextbound etc.
         */
-       klass->flags = tb->attrs;
+       mono_class_set_flags (klass, tb->attrs);
        klass->has_cctor = 1;
 
        mono_class_setup_parent (klass, klass->parent);
@@ -3490,7 +3497,7 @@ ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
         *
         * Together with this we must ensure the contents of all instances to match the created type.
         */
-       if (domain->type_hash && klass->generic_container) {
+       if (domain->type_hash && mono_class_is_gtd (klass)) {
                struct remove_instantiations_user_data data;
                data.klass = klass;
                data.error = &error;
@@ -3741,8 +3748,8 @@ ensure_complete_type (MonoClass *klass, MonoError *error)
                //g_assert (klass->wastypebuilder);
        }
 
-       if (klass->generic_class) {
-               MonoGenericInst *inst = klass->generic_class->context.class_inst;
+       if (mono_class_is_ginst (klass)) {
+               MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
                int i;
 
                for (i = 0; i < inst->type_argc; ++i) {
index d22470415e84e1891759e5a31df748eacde76531..afd2bcc9e366b4b188cc4321437877f69327b172 100644 (file)
@@ -424,18 +424,20 @@ domain_remove (ThreadPoolDomain *tpdomain)
 static ThreadPoolDomain *
 domain_get (MonoDomain *domain, gboolean create)
 {
-       ThreadPoolDomain *tpdomain = NULL;
        guint i;
 
        g_assert (domain);
 
        for (i = 0; i < threadpool->domains->len; ++i) {
+               ThreadPoolDomain *tpdomain;
+
                tpdomain = (ThreadPoolDomain *)g_ptr_array_index (threadpool->domains, i);
                if (tpdomain->domain == domain)
                        return tpdomain;
        }
 
        if (create) {
+               ThreadPoolDomain *tpdomain;
                ThreadPoolDomainCleanupSemaphore *cleanup_semaphore;
                cleanup_semaphore = g_new0 (ThreadPoolDomainCleanupSemaphore, 1);
                cleanup_semaphore->ref = 2;
@@ -447,9 +449,11 @@ domain_get (MonoDomain *domain, gboolean create)
                tpdomain = g_new0 (ThreadPoolDomain, 1);
                tpdomain->domain = domain;
                domain_add (tpdomain);
+
+               return tpdomain;
        }
 
-       return tpdomain;
+       return NULL;
 }
 
 static void
index a7fd76f1f1c435ef6cc7888fdf1153f2a9ff6df8..84f2c15e98fc5e19d14ad4990b018da5766fb9e6 100644 (file)
@@ -70,7 +70,7 @@ void mono_threads_install_cleanup (MonoThreadCleanupFunc func);
 
 void ves_icall_System_Threading_Thread_ConstructInternalThread (MonoThread *this_obj);
 HANDLE ves_icall_System_Threading_Thread_Thread_internal(MonoThread *this_obj, MonoObject *start);
-void ves_icall_System_Threading_InternalThread_Thread_free_internal(MonoInternalThread *this_obj, HANDLE thread);
+void ves_icall_System_Threading_InternalThread_Thread_free_internal(MonoInternalThread *this_obj);
 void ves_icall_System_Threading_Thread_Sleep_internal(gint32 ms);
 gboolean ves_icall_System_Threading_Thread_Join_internal(MonoThread *this_obj, int ms);
 gint32 ves_icall_System_Threading_Thread_GetDomainID (void);
index 2ae43aab0ae3be675b979e4cb5756fc1d6ed169a..315183a7762c421abfc3a07ef7c6c672268d02f8 100644 (file)
@@ -44,7 +44,9 @@
 #include <mono/utils/mono-memory-model.h>
 #include <mono/utils/mono-threads-coop.h>
 #include <mono/utils/mono-error-internals.h>
-#include <mono/utils/w32handle.h>
+#include <mono/utils/os-event.h>
+#include <mono/utils/mono-threads-debug.h>
+#include <mono/metadata/w32handle.h>
 #include <mono/metadata/w32event.h>
 #include <mono/metadata/w32mutex.h>
 
@@ -213,7 +215,7 @@ static mono_mutex_t interlocked_mutex;
 static gint32 thread_interruption_requested = 0;
 
 /* Event signaled when a thread changes its background mode */
-static HANDLE background_change_event;
+static MonoOSEvent background_change_event;
 
 static gboolean shutting_down = FALSE;
 
@@ -539,22 +541,18 @@ set_current_thread_for_domain (MonoDomain *domain, MonoInternalThread *thread, M
 }
 
 static MonoThread*
-create_thread_object (MonoDomain *domain)
+create_thread_object (MonoDomain *domain, MonoInternalThread *internal)
 {
+       MonoThread *thread;
+       MonoVTable *vtable;
        MonoError error;
-       MonoVTable *vt = mono_class_vtable (domain, mono_defaults.thread_class);
-       MonoThread *t = (MonoThread*)mono_object_new_mature (vt, &error);
-       /* only possible failure mode is OOM, from which we don't expect to recover. */
-       mono_error_assert_ok (&error);
-       return t;
-}
 
-static MonoThread*
-new_thread_with_internal (MonoDomain *domain, MonoInternalThread *internal)
-{
-       MonoThread *thread;
+       vtable = mono_class_vtable (domain, mono_defaults.thread_class);
+       g_assert (vtable);
 
-       thread = create_thread_object (domain);
+       thread = (MonoThread*)mono_object_new_mature (vtable, &error);
+       /* only possible failure mode is OOM, from which we don't expect to recover. */
+       mono_error_assert_ok (&error);
 
        MONO_OBJECT_SETREF (thread, internal_thread, internal);
 
@@ -562,7 +560,7 @@ new_thread_with_internal (MonoDomain *domain, MonoInternalThread *internal)
 }
 
 static MonoInternalThread*
-create_internal_thread (void)
+create_internal_thread_object (void)
 {
        MonoError error;
        MonoInternalThread *thread;
@@ -585,6 +583,9 @@ create_internal_thread (void)
 
        thread->priority = MONO_THREAD_PRIORITY_NORMAL;
 
+       thread->suspended = g_new0 (MonoOSEvent, 1);
+       mono_os_event_init (thread->suspended, TRUE, TRUE);
+
        return thread;
 }
 
@@ -592,7 +593,6 @@ static void
 mono_thread_internal_set_priority (MonoInternalThread *internal, MonoThreadPriority priority)
 {
        g_assert (internal);
-       g_assert (internal->handle);
 
        g_assert (priority >= MONO_THREAD_PRIORITY_LOWEST);
        g_assert (priority <= MONO_THREAD_PRIORITY_HIGHEST);
@@ -601,7 +601,9 @@ mono_thread_internal_set_priority (MonoInternalThread *internal, MonoThreadPrior
 #ifdef HOST_WIN32
        BOOL res;
 
-       res = SetThreadPriority (internal->handle, priority - 2);
+       g_assert (internal->native_handle);
+
+       res = SetThreadPriority (internal->native_handle, priority - 2);
        if (!res)
                g_error ("%s: SetThreadPriority failed, error %d", __func__, GetLastError ());
 #else /* HOST_WIN32 */
@@ -676,7 +678,10 @@ mono_thread_attach_internal (MonoThread *thread, gboolean force_attach, gboolean
        info = mono_thread_info_current ();
 
        internal = thread->internal_thread;
-       internal->handle = mono_thread_info_duplicate_handle (info);
+       internal->handle = mono_threads_open_thread_handle (info->handle);
+#ifdef HOST_WIN32
+       internal->native_handle = OpenThread (THREAD_ALL_ACCESS, FALSE, GetCurrentThreadId ());
+#endif
        internal->tid = MONO_NATIVE_THREAD_ID_TO_UINT (mono_native_thread_id_get ());
        internal->thread_info = info;
        internal->small_id = info->small_id;
@@ -727,7 +732,7 @@ mono_thread_attach_internal (MonoThread *thread, gboolean force_attach, gboolean
 
        g_assert (!internal->root_domain_thread);
        if (domain != root_domain)
-               MONO_OBJECT_SETREF (internal, root_domain_thread, new_thread_with_internal (root_domain, internal));
+               MONO_OBJECT_SETREF (internal, root_domain_thread, create_thread_object (root_domain, internal));
        else
                MONO_OBJECT_SETREF (internal, root_domain_thread, thread);
 
@@ -890,9 +895,6 @@ static gsize WINAPI start_wrapper(void *data)
 {
        volatile gsize dummy;
 
-       /* Avoid scanning the frames above this frame during a GC */
-       mono_gc_set_stack_end ((void*)&dummy);
-
        return start_wrapper_internal ((StartInfo*) data, (gsize*) &dummy);
 }
 
@@ -907,7 +909,7 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, MonoObject *sta
        gboolean threadpool_thread, guint32 stack_size, MonoError *error)
 {
        StartInfo *start_info = NULL;
-       HANDLE thread_handle;
+       MonoThreadHandle *thread_handle;
        MonoNativeThreadId tid;
        gboolean ret;
        gsize stack_set_size;
@@ -1029,11 +1031,9 @@ mono_thread_create_internal (MonoDomain *domain, gpointer func, gpointer arg, gb
 
        mono_error_init (error);
 
-       thread = create_thread_object (domain);
+       internal = create_internal_thread_object ();
 
-       internal = create_internal_thread ();
-
-       MONO_OBJECT_SETREF (thread, internal_thread, internal);
+       thread = create_thread_object (domain, internal);
 
        LOCK_THREAD (internal);
 
@@ -1088,9 +1088,9 @@ mono_thread_attach_full (MonoDomain *domain, gboolean force_attach)
 
        tid=mono_native_thread_id_get ();
 
-       internal = create_internal_thread ();
+       internal = create_internal_thread_object ();
 
-       thread = new_thread_with_internal (domain, internal);
+       thread = create_thread_object (domain, internal);
 
        if (!mono_thread_attach_internal (thread, force_attach, TRUE, &stack_ptr)) {
                /* Mono is shutting down, so just wait for the end */
@@ -1197,7 +1197,7 @@ mono_thread_exit (void)
        if (mono_thread_get_main () && (thread == mono_thread_get_main ()->internal_thread))
                exit (mono_environment_exitcode_get ());
 
-       mono_thread_info_exit ();
+       mono_thread_info_exit (0);
 }
 
 void
@@ -1205,7 +1205,7 @@ ves_icall_System_Threading_Thread_ConstructInternalThread (MonoThread *this_obj)
 {
        MonoInternalThread *internal;
 
-       internal = create_internal_thread ();
+       internal = create_internal_thread_object ();
 
        internal->state = ThreadState_Unstarted;
 
@@ -1258,17 +1258,23 @@ ves_icall_System_Threading_Thread_Thread_internal (MonoThread *this_obj,
  * This is called from the finalizer of the internal thread object.
  */
 void
-ves_icall_System_Threading_InternalThread_Thread_free_internal (MonoInternalThread *this_obj, HANDLE thread)
+ves_icall_System_Threading_InternalThread_Thread_free_internal (MonoInternalThread *this_obj)
 {
-       THREAD_DEBUG (g_message ("%s: Closing thread %p, handle %p", __func__, this, thread));
+       THREAD_DEBUG (g_message ("%s: Closing thread %p, handle %p", __func__, this, this_obj->handle));
 
        /*
         * Since threads keep a reference to their thread object while running, by the time this function is called,
         * the thread has already exited/detached, i.e. thread_cleanup () has ran. The exception is during shutdown,
         * when thread_cleanup () can be called after this.
         */
-       if (thread)
-               mono_threads_close_thread_handle (thread);
+       if (this_obj->handle) {
+               mono_threads_close_thread_handle (this_obj->handle);
+               this_obj->handle = NULL;
+       }
+
+#if HOST_WIN32
+       CloseHandle (this_obj->native_handle);
+#endif
 
        if (this_obj->synch_cs) {
                MonoCoopMutex *synch_cs = this_obj->synch_cs;
@@ -1282,6 +1288,11 @@ ves_icall_System_Threading_InternalThread_Thread_free_internal (MonoInternalThre
                this_obj->name = NULL;
                g_free (name);
        }
+
+       g_assert (this_obj->suspended);
+       mono_os_event_destroy (this_obj->suspended);
+       g_free (this_obj->suspended);
+       this_obj->suspended = NULL;
 }
 
 void
@@ -1515,7 +1526,7 @@ ves_icall_System_Threading_Thread_SetPriority (MonoThread *this_obj, int priorit
 
        LOCK_THREAD (internal);
        internal->priority = priority;
-       if (internal->handle != NULL)
+       if (internal->thread_info != NULL)
                mono_thread_internal_set_priority (internal, priority);
        UNLOCK_THREAD (internal);
 }
@@ -1569,7 +1580,7 @@ mono_thread_current (void)
 
        if (!*current_thread_ptr) {
                g_assert (domain != mono_get_root_domain ());
-               *current_thread_ptr = new_thread_with_internal (domain, internal);
+               *current_thread_ptr = create_thread_object (domain, internal);
        }
        return *current_thread_ptr;
 }
@@ -1586,7 +1597,7 @@ mono_thread_current_for_thread (MonoInternalThread *internal)
 
        if (!*current_thread_ptr) {
                g_assert (domain != mono_get_root_domain ());
-               *current_thread_ptr = new_thread_with_internal (domain, internal);
+               *current_thread_ptr = create_thread_object (domain, internal);
        }
        return *current_thread_ptr;
 }
@@ -1603,7 +1614,7 @@ gboolean
 ves_icall_System_Threading_Thread_Join_internal(MonoThread *this_obj, int ms)
 {
        MonoInternalThread *thread = this_obj->internal_thread;
-       HANDLE handle = thread->handle;
+       MonoThreadHandle *handle = thread->handle;
        MonoInternalThread *cur_thread = mono_thread_internal_current ();
        gboolean ret;
 
@@ -1629,12 +1640,12 @@ ves_icall_System_Threading_Thread_Join_internal(MonoThread *this_obj, int ms)
        mono_thread_set_state (cur_thread, ThreadState_WaitSleepJoin);
 
        MONO_ENTER_GC_SAFE;
-       ret=WaitForSingleObjectEx (handle, ms, TRUE);
+       ret=mono_thread_info_wait_one_handle (handle, ms, TRUE);
        MONO_EXIT_GC_SAFE;
 
        mono_thread_clr_state (cur_thread, ThreadState_WaitSleepJoin);
        
-       if(ret==WAIT_OBJECT_0) {
+       if(ret==MONO_THREAD_INFO_WAIT_RET_SUCCESS_0) {
                THREAD_DEBUG (g_message ("%s: join successful", __func__));
 
                return(TRUE);
@@ -2072,7 +2083,7 @@ ves_icall_System_Threading_Thread_ClrState (MonoInternalThread* this_obj, guint3
                 * be notified, since it has to rebuild the list of threads to
                 * wait for.
                 */
-               mono_w32event_set (background_change_event);
+               mono_os_event_set (&background_change_event);
        }
 }
 
@@ -2086,7 +2097,7 @@ ves_icall_System_Threading_Thread_SetState (MonoInternalThread* this_obj, guint3
                 * be notified, since it has to rebuild the list of threads to
                 * wait for.
                 */
-               mono_w32event_set (background_change_event);
+               mono_os_event_set (&background_change_event);
        }
 }
 
@@ -2324,6 +2335,8 @@ mono_thread_suspend (MonoInternalThread *thread)
        }
        
        thread->state |= ThreadState_SuspendRequested;
+       if (mono_threads_is_coop_enabled ())
+               mono_os_event_reset (thread->suspended);
 
        if (thread == mono_thread_internal_current ()) {
                /* calls UNLOCK_THREAD (thread) */
@@ -2350,6 +2363,9 @@ static gboolean
 mono_thread_resume (MonoInternalThread *thread)
 {
        if ((thread->state & ThreadState_SuspendRequested) != 0) {
+               // MOSTLY_ASYNC_SAFE_PRINTF ("RESUME (1) thread %p\n", thread_get_tid (thread));
+               if (mono_threads_is_coop_enabled ())
+                       mono_os_event_set (thread->suspended);
                thread->state &= ~ThreadState_SuspendRequested;
                return TRUE;
        }
@@ -2359,16 +2375,23 @@ mono_thread_resume (MonoInternalThread *thread)
                (thread->state & ThreadState_Aborted) != 0 || 
                (thread->state & ThreadState_Stopped) != 0)
        {
+               // MOSTLY_ASYNC_SAFE_PRINTF ("RESUME (2) thread %p\n", thread_get_tid (thread));
                return FALSE;
        }
 
-       UNLOCK_THREAD (thread);
+       // MOSTLY_ASYNC_SAFE_PRINTF ("RESUME (3) thread %p\n", thread_get_tid (thread));
 
-       /* Awake the thread */
-       if (!mono_thread_info_resume (thread_get_tid (thread)))
-               return FALSE;
+       if (mono_threads_is_coop_enabled ()) {
+               mono_os_event_set (thread->suspended);
+       } else {
+               UNLOCK_THREAD (thread);
 
-       LOCK_THREAD (thread);
+               /* Awake the thread */
+               if (!mono_thread_info_resume (thread_get_tid (thread)))
+                       return FALSE;
+
+               LOCK_THREAD (thread);
+       }
 
        thread->state &= ~ThreadState_Suspended;
 
@@ -2837,8 +2860,7 @@ void mono_thread_init (MonoThreadStartCB start_cb,
        mono_os_mutex_init_recursive(&interlocked_mutex);
        mono_os_mutex_init_recursive(&joinable_threads_mutex);
        
-       background_change_event = mono_w32event_create (TRUE, FALSE);
-       g_assert(background_change_event != NULL);
+       mono_os_event_init (&background_change_event, TRUE, FALSE);
        
        mono_init_static_data_info (&thread_static_info);
        mono_init_static_data_info (&context_static_info);
@@ -2847,25 +2869,18 @@ void mono_thread_init (MonoThreadStartCB start_cb,
 
        mono_thread_start_cb = start_cb;
        mono_thread_attach_cb = attach_cb;
-
-       /* Get a pseudo handle to the current process.  This is just a
-        * kludge so that wapi can build a process handle if needed.
-        * As a pseudo handle is returned, we don't need to clean
-        * anything up.
-        */
-       GetCurrentProcess ();
 }
 
 void mono_thread_cleanup (void)
 {
-#if !defined(RUN_IN_SUBTHREAD)
+#if !defined(RUN_IN_SUBTHREAD) && !defined(HOST_WIN32)
        /* The main thread must abandon any held mutexes (particularly
         * important for named mutexes as they are shared across
         * processes, see bug 74680.)  This will happen when the
         * thread exits, but if it's not running in a subthread it
         * won't exit in time.
         */
-       mono_thread_info_set_exited (mono_thread_info_current ());
+       mono_w32mutex_abandon ();
 #endif
 
 #if 0
@@ -2877,7 +2892,7 @@ void mono_thread_cleanup (void)
        mono_os_mutex_destroy (&interlocked_mutex);
        mono_os_mutex_destroy (&delayed_free_table_mutex);
        mono_os_mutex_destroy (&small_id_mutex);
-       CloseHandle (background_change_event);
+       mono_os_event_destroy (&background_change_event);
 #endif
 
        mono_native_tls_free (current_object_key);
@@ -2909,7 +2924,7 @@ static void print_tids (gpointer key, gpointer value, gpointer user)
 
 struct wait_data 
 {
-       HANDLE handles[MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS];
+       MonoThreadHandle *handles[MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS];
        MonoInternalThread *threads[MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS];
        guint32 num;
 };
@@ -2917,15 +2932,16 @@ struct wait_data
 static void
 wait_for_tids (struct wait_data *wait, guint32 timeout)
 {
-       guint32 i, ret;
+       guint32 i;
+       MonoThreadInfoWaitRet ret;
        
        THREAD_DEBUG (g_message("%s: %d threads to wait for in this batch", __func__, wait->num));
 
        MONO_ENTER_GC_SAFE;
-       ret=WaitForMultipleObjectsEx(wait->num, wait->handles, TRUE, timeout, TRUE);
+       ret = mono_thread_info_wait_multiple_handle(wait->handles, wait->num, NULL, TRUE, timeout, TRUE);
        MONO_EXIT_GC_SAFE;
 
-       if(ret==WAIT_FAILED) {
+       if(ret==MONO_THREAD_INFO_WAIT_RET_FAILED) {
                /* See the comment in build_wait_tids() */
                THREAD_DEBUG (g_message ("%s: Wait failed", __func__));
                return;
@@ -2934,7 +2950,7 @@ wait_for_tids (struct wait_data *wait, guint32 timeout)
        for(i=0; i<wait->num; i++)
                mono_threads_close_thread_handle (wait->handles [i]);
 
-       if (ret == WAIT_TIMEOUT)
+       if (ret == MONO_THREAD_INFO_WAIT_RET_TIMEOUT)
                return;
 
        for(i=0; i<wait->num; i++) {
@@ -2951,24 +2967,19 @@ wait_for_tids (struct wait_data *wait, guint32 timeout)
 
 static void wait_for_tids_or_state_change (struct wait_data *wait, guint32 timeout)
 {
-       guint32 i, ret, count;
+       guint32 i;
+       MonoThreadInfoWaitRet ret;
        
        THREAD_DEBUG (g_message("%s: %d threads to wait for in this batch", __func__, wait->num));
 
-       /* Add the thread state change event, so it wakes up if a thread changes
-        * to background mode.
-        */
-       count = wait->num;
-       if (count < MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS) {
-               wait->handles [count] = background_change_event;
-               count++;
-       }
+       /* Add the thread state change event, so it wakes
+        * up if a thread changes to background mode. */
 
        MONO_ENTER_GC_SAFE;
-       ret=WaitForMultipleObjectsEx (count, wait->handles, FALSE, timeout, TRUE);
+       ret = mono_thread_info_wait_multiple_handle (wait->handles, wait->num, &background_change_event, FALSE, timeout, TRUE);
        MONO_EXIT_GC_SAFE;
 
-       if(ret==WAIT_FAILED) {
+       if(ret==MONO_THREAD_INFO_WAIT_RET_FAILED) {
                /* See the comment in build_wait_tids() */
                THREAD_DEBUG (g_message ("%s: Wait failed", __func__));
                return;
@@ -2977,7 +2988,7 @@ static void wait_for_tids_or_state_change (struct wait_data *wait, guint32 timeo
        for(i=0; i<wait->num; i++)
                mono_threads_close_thread_handle (wait->handles [i]);
 
-       if (ret == WAIT_TIMEOUT)
+       if (ret == MONO_THREAD_INFO_WAIT_RET_TIMEOUT)
                return;
        
        if (ret < wait->num) {
@@ -2996,8 +3007,7 @@ static void build_wait_tids (gpointer key, gpointer value, gpointer user)
 {
        struct wait_data *wait=(struct wait_data *)user;
 
-       if(wait->num<MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS) {
-               HANDLE handle;
+       if(wait->num<MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS - 1) {
                MonoInternalThread *thread=(MonoInternalThread *)value;
 
                /* Ignore background threads, we abort them later */
@@ -3027,15 +3037,9 @@ static void build_wait_tids (gpointer key, gpointer value, gpointer user)
                        return;
                }
 
-               handle = mono_threads_open_thread_handle (thread->handle, thread_get_tid (thread));
-               if (handle == NULL) {
-                       THREAD_DEBUG (g_message ("%s: ignoring unopenable thread %"G_GSIZE_FORMAT, __func__, (gsize)thread->tid));
-                       return;
-               }
-               
                THREAD_DEBUG (g_message ("%s: Invoking mono_thread_manage callback on thread %p", __func__, thread));
                if ((thread->manage_callback == NULL) || (thread->manage_callback (thread->root_domain_thread) == TRUE)) {
-                       wait->handles[wait->num]=handle;
+                       wait->handles[wait->num]=mono_threads_open_thread_handle (thread->handle);
                        wait->threads[wait->num]=thread;
                        wait->num++;
 
@@ -3058,7 +3062,6 @@ remove_and_abort_threads (gpointer key, gpointer value, gpointer user)
        struct wait_data *wait=(struct wait_data *)user;
        MonoNativeThreadId self = mono_native_thread_id_get ();
        MonoInternalThread *thread = (MonoInternalThread *)value;
-       HANDLE handle;
 
        if (wait->num >= MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS)
                return FALSE;
@@ -3068,11 +3071,7 @@ remove_and_abort_threads (gpointer key, gpointer value, gpointer user)
             && (thread->state & ThreadState_Background) != 0
             && (thread->flags & MONO_THREAD_FLAG_DONT_MANAGE) == 0
        ) {
-               handle = mono_threads_open_thread_handle (thread->handle, thread_get_tid (thread));
-               if (handle == NULL)
-                       return FALSE;
-
-               wait->handles[wait->num] = handle;
+               wait->handles[wait->num] = mono_threads_open_thread_handle (thread->handle);
                wait->threads[wait->num] = thread;
                wait->num++;
 
@@ -3120,7 +3119,7 @@ mono_threads_set_shutting_down (void)
                mono_thread_detach_internal (current_thread);
 
                /* Wake up other threads potentially waiting for us */
-               mono_thread_info_exit ();
+               mono_thread_info_exit (0);
        } else {
                shutting_down = TRUE;
 
@@ -3128,7 +3127,7 @@ mono_threads_set_shutting_down (void)
                 * interrupt the main thread if it is waiting for all
                 * the other threads.
                 */
-               mono_w32event_set (background_change_event);
+               mono_os_event_set (&background_change_event);
                
                mono_threads_unlock ();
        }
@@ -3161,7 +3160,7 @@ void mono_thread_manage (void)
                THREAD_DEBUG (g_message ("%s: There are %d threads to join", __func__, mono_g_hash_table_size (threads));
                        mono_g_hash_table_foreach (threads, print_tids, NULL));
        
-               mono_w32event_reset (background_change_event);
+               mono_os_event_reset (&background_change_event);
                wait->num=0;
                /*We must zero all InternalThread pointers to avoid making the GC unhappy.*/
                memset (wait->threads, 0, MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS * SIZEOF_VOID_P);
@@ -3215,7 +3214,6 @@ collect_threads_for_suspend (gpointer key, gpointer value, gpointer user_data)
 {
        MonoInternalThread *thread = (MonoInternalThread*)value;
        struct wait_data *wait = (struct wait_data*)user_data;
-       HANDLE handle;
 
        /* 
         * We try to exclude threads early, to avoid running into the MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS
@@ -3227,11 +3225,7 @@ collect_threads_for_suspend (gpointer key, gpointer value, gpointer user_data)
                return;
 
        if (wait->num<MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS) {
-               handle = mono_threads_open_thread_handle (thread->handle, thread_get_tid (thread));
-               if (handle == NULL)
-                       return;
-
-               wait->handles [wait->num] = handle;
+               wait->handles [wait->num] = mono_threads_open_thread_handle (thread->handle);
                wait->threads [wait->num] = thread;
                wait->num++;
        }
@@ -3317,6 +3311,8 @@ void mono_thread_suspend_all_other_threads (void)
                                thread->state &= ~ThreadState_AbortRequested;
                        
                        thread->state |= ThreadState_SuspendRequested;
+                       if (mono_threads_is_coop_enabled ())
+                               mono_os_event_reset (thread->suspended);
 
                        /* Signal the thread to suspend + calls UNLOCK_THREAD (thread) */
                        async_suspend_internal (thread, TRUE);
@@ -3755,10 +3751,7 @@ collect_appdomain_thread (gpointer key, gpointer value, gpointer user_data)
                /* printf ("ABORTING THREAD %p BECAUSE IT REFERENCES DOMAIN %s.\n", thread->tid, domain->friendly_name); */
 
                if(data->wait.num<MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS) {
-                       HANDLE handle = mono_threads_open_thread_handle (thread->handle, thread_get_tid (thread));
-                       if (handle == NULL)
-                               return;
-                       data->wait.handles [data->wait.num] = handle;
+                       data->wait.handles [data->wait.num] = mono_threads_open_thread_handle (thread->handle);
                        data->wait.threads [data->wait.num] = thread;
                        data->wait.num++;
                } else {
@@ -4417,7 +4410,7 @@ mono_thread_request_interruption (gboolean running_managed)
                   or similar */
                /* Our implementation of this function ignores the func argument */
 #ifdef HOST_WIN32
-               QueueUserAPC ((PAPCFUNC)dummy_apc, thread->handle, (ULONG_PTR)NULL);
+               QueueUserAPC ((PAPCFUNC)dummy_apc, thread->native_handle, (ULONG_PTR)NULL);
 #else
                mono_thread_info_self_interrupt ();
 #endif
@@ -4644,11 +4637,24 @@ mono_runtime_has_tls_get (void)
 static void
 self_interrupt_thread (void *_unused)
 {
-       MonoThreadInfo *info = mono_thread_info_current ();
-       MonoException *exc = mono_thread_execute_interruption ();
-       if (exc) /*We must use _with_context since we didn't trampoline into the runtime*/
-               mono_raise_exception_with_context (exc, &info->thread_saved_state [ASYNC_SUSPEND_STATE_INDEX].ctx); /* FIXME using thread_saved_state [ASYNC_SUSPEND_STATE_INDEX] can race with another suspend coming in. */
-       g_assert_not_reached (); /*this MUST not happen since we can't resume from an async call*/
+       MonoException *exc;
+       MonoThreadInfo *info;
+
+       exc = mono_thread_execute_interruption ();
+       if (!exc) {
+               if (mono_threads_is_coop_enabled ()) {
+                       /* We can return from an async call in coop, as
+                        * it's simply called when exiting the safepoint */
+                       return;
+               }
+
+               g_error ("%s: we can't resume from an async call", __func__);
+       }
+
+       info = mono_thread_info_current ();
+
+       /* We must use _with_context since we didn't trampoline into the runtime */
+       mono_raise_exception_with_context (exc, &info->thread_saved_state [ASYNC_SUSPEND_STATE_INDEX].ctx); /* FIXME using thread_saved_state [ASYNC_SUSPEND_STATE_INDEX] can race with another suspend coming in. */
 }
 
 static gboolean
@@ -4799,9 +4805,14 @@ async_suspend_critical (MonoThreadInfo *info, gpointer ud)
        running_managed = mono_jit_info_match (ji, MONO_CONTEXT_GET_IP (&mono_thread_info_get_suspend_state (info)->ctx));
 
        if (running_managed && !protected_wrapper) {
-               thread->state &= ~ThreadState_SuspendRequested;
-               thread->state |= ThreadState_Suspended;
-               return KeepSuspended;
+               if (mono_threads_is_coop_enabled ()) {
+                       mono_thread_info_setup_async_call (info, self_interrupt_thread, NULL);
+                       return MonoResumeThread;
+               } else {
+                       thread->state &= ~ThreadState_SuspendRequested;
+                       thread->state |= ThreadState_Suspended;
+                       return KeepSuspended;
+               }
        } else {
                if (InterlockedCompareExchange (&thread->interruption_requested, 1, 0) == 0)
                        InterlockedIncrement (&thread_interruption_requested);
@@ -4820,6 +4831,8 @@ async_suspend_internal (MonoInternalThread *thread, gboolean interrupt)
 
        g_assert (thread != mono_thread_internal_current ());
 
+       // MOSTLY_ASYNC_SAFE_PRINTF ("ASYNC SUSPEND thread %p\n", thread_get_tid (thread));
+
        data.thread = thread;
        data.interrupt = interrupt;
        data.interrupt_token = NULL;
@@ -4839,13 +4852,29 @@ self_suspend_internal (void)
 
        thread = mono_thread_internal_current ();
 
-       mono_thread_info_begin_self_suspend ();
+       // MOSTLY_ASYNC_SAFE_PRINTF ("SELF SUSPEND thread %p\n", thread_get_tid (thread));
+
+       if (!mono_threads_is_coop_enabled ())
+               mono_thread_info_begin_self_suspend ();
+
        thread->state &= ~ThreadState_SuspendRequested;
        thread->state |= ThreadState_Suspended;
 
        UNLOCK_THREAD (thread);
 
-       mono_thread_info_end_self_suspend ();
+       if (!mono_threads_is_coop_enabled ())
+               mono_thread_info_end_self_suspend ();
+       else {
+               MonoOSEvent *event;
+               MonoOSEventWaitRet res;
+
+               event = thread->suspended;
+
+               MONO_ENTER_GC_SAFE;
+               res = mono_os_event_wait_one (event, MONO_INFINITE_WAIT);
+               g_assert (res == MONO_OS_EVENT_WAIT_RET_SUCCESS_0);
+               MONO_EXIT_GC_SAFE;
+       }
 }
 
 /*
index 7be7267baa5d7bdb303b6809640bb58b9f88c18b..baed2947614e4a0611992f45d62a2a541f89e3fb 100644 (file)
@@ -529,7 +529,7 @@ mono_type_is_valid_type_in_context_full (MonoType *type, MonoGenericContext *con
                if (klass->byval_arg.type != type->type)
                        return mono_type_is_valid_type_in_context_full (&klass->byval_arg, context, check_gtd);
 
-               if (check_gtd && klass->generic_container)
+               if (check_gtd && mono_class_is_gtd (klass))
                        return FALSE;
                break;
        }
@@ -597,11 +597,11 @@ is_valid_generic_instantiation (MonoGenericContainer *gc, MonoGenericContext *co
                 * The type A <K> has a parent B<K>, that is inflated into the GTD B<>.
                 * Since A<K> is open, thus not instantiatable, this is valid.
                 */
-               if (paramClass->generic_container && param_type->type != MONO_TYPE_GENERICINST && !ginst->is_open)
+               if (mono_class_is_gtd (paramClass) && param_type->type != MONO_TYPE_GENERICINST && !ginst->is_open)
                        return FALSE;
 
                /*it's not safe to call mono_class_init from here*/
-               if (paramClass->generic_class && !paramClass->inited) {
+               if (mono_class_is_ginst (paramClass) && !paramClass->inited) {
                        if (!mono_class_is_valid_generic_instantiation (NULL, paramClass))
                                return FALSE;
                }
@@ -754,9 +754,9 @@ verifier_get_generic_param_from_type (VerifyContext *ctx, MonoType *type)
 
        if (type->type == MONO_TYPE_VAR) {
                MonoClass *gtd = method->klass;
-               if (gtd->generic_class)
-                       gtd = gtd->generic_class->container_class;
-               gc = gtd->generic_container;
+               if (mono_class_is_ginst (gtd))
+                       gtd = mono_class_get_generic_class (gtd)->container_class;
+               gc = mono_class_try_get_generic_container (gtd);
        } else { //MVAR
                MonoMethod *gmd = method;
                if (method->is_inflated)
@@ -831,9 +831,9 @@ mono_method_repect_method_constraints (VerifyContext *ctx, MonoMethod *method)
 static gboolean
 mono_class_repect_method_constraints (VerifyContext *ctx, MonoClass *klass)
 {
-       MonoGenericClass *gklass = klass->generic_class;
+       MonoGenericClass *gklass = mono_class_get_generic_class (klass);
        MonoGenericInst *ginst = gklass->context.class_inst;
-       MonoGenericContainer *gc = gklass->container_class->generic_container;
+       MonoGenericContainer *gc = mono_class_get_generic_container (gklass->container_class);
        return !gc || generic_arguments_respect_constraints (ctx, gc, &gklass->context, ginst);
 }
 
@@ -854,9 +854,9 @@ mono_method_is_valid_generic_instantiation (VerifyContext *ctx, MonoMethod *meth
 static gboolean
 mono_class_is_valid_generic_instantiation (VerifyContext *ctx, MonoClass *klass)
 {
-       MonoGenericClass *gklass = klass->generic_class;
+       MonoGenericClass *gklass = mono_class_get_generic_class (klass);
        MonoGenericInst *ginst = gklass->context.class_inst;
-       MonoGenericContainer *gc = gklass->container_class->generic_container;
+       MonoGenericContainer *gc = mono_class_get_generic_container (gklass->container_class);
        if (ctx && !is_valid_generic_instantiation_in_context (ctx, ginst, TRUE))
                return FALSE;
        return is_valid_generic_instantiation (gc, &gklass->context, ginst);
@@ -887,19 +887,19 @@ mono_type_is_valid_in_context (VerifyContext *ctx, MonoType *type)
        klass = mono_class_from_mono_type (type);
        mono_class_init (klass);
        if (mono_class_has_failure (klass)) {
-               if (klass->generic_class && !mono_class_is_valid_generic_instantiation (NULL, klass))
+               if (mono_class_is_ginst (klass) && !mono_class_is_valid_generic_instantiation (NULL, klass))
                        ADD_VERIFY_ERROR2 (ctx, g_strdup_printf ("Invalid generic instantiation of type %s.%s at 0x%04x", klass->name_space, klass->name, ctx->ip_offset), MONO_EXCEPTION_TYPE_LOAD);
                else
                        ADD_VERIFY_ERROR2 (ctx, g_strdup_printf ("Could not load type %s.%s at 0x%04x", klass->name_space, klass->name, ctx->ip_offset), MONO_EXCEPTION_TYPE_LOAD);
                return FALSE;
        }
 
-       if (klass->generic_class && mono_class_has_failure (klass->generic_class->container_class)) {
+       if (mono_class_is_ginst (klass) && mono_class_has_failure (mono_class_get_generic_class (klass)->container_class)) {
                ADD_VERIFY_ERROR2 (ctx, g_strdup_printf ("Could not load type %s.%s at 0x%04x", klass->name_space, klass->name, ctx->ip_offset), MONO_EXCEPTION_TYPE_LOAD);
                return FALSE;
        }
 
-       if (!klass->generic_class)
+       if (!mono_class_is_ginst (klass))
                return TRUE;
 
        if (!mono_class_is_valid_generic_instantiation (ctx, klass)) {
@@ -1678,7 +1678,7 @@ get_boxable_mono_type (VerifyContext* ctx, int token, const char *opcode)
        if (!(klass = mono_class_from_mono_type (type)))
                ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Could not retrieve type token for %s at 0x%04x", opcode, ctx->ip_offset));
 
-       if (klass->generic_container && type->type != MONO_TYPE_GENERICINST)
+       if (mono_class_is_gtd (klass) && type->type != MONO_TYPE_GENERICINST)
                CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Cannot use the generic type definition in a boxable type position for %s at 0x%04x", opcode, ctx->ip_offset));      
 
        check_unverifiable_type (ctx, type);
@@ -2188,14 +2188,14 @@ verifier_class_is_assignable_from (MonoClass *target, MonoClass *candidate)
        if (mono_class_is_assignable_from (target, candidate))
                return TRUE;
 
-       if (!MONO_CLASS_IS_INTERFACE (target) || !target->generic_class || candidate->rank != 1)
+       if (!MONO_CLASS_IS_INTERFACE (target) || !mono_class_is_ginst (target) || candidate->rank != 1)
                return FALSE;
 
-       iface_gtd = target->generic_class->container_class;
+       iface_gtd = mono_class_get_generic_class (target)->container_class;
        if (iface_gtd != mono_defaults.generic_ilist_class && iface_gtd != get_icollection_class () && iface_gtd != get_ienumerable_class ())
                return FALSE;
 
-       target = mono_class_from_mono_type (target->generic_class->context.class_inst->type_argv [0]);
+       target = mono_class_from_mono_type (mono_class_get_generic_class (target)->context.class_inst->type_argv [0]);
        candidate = candidate->element_class;
 
        return TRUE;
@@ -2674,7 +2674,7 @@ verify_ldftn_delegate (VerifyContext *ctx, MonoClass *delegate, ILStackDesc *val
         * the object is a this arg (comes from a ldarg.0), and there is no starg.0.
         * This rules doesn't apply if the object on stack is a boxed valuetype.
         */
-       if ((method->flags & METHOD_ATTRIBUTE_VIRTUAL) && !(method->flags & METHOD_ATTRIBUTE_FINAL) && !(method->klass->flags & TYPE_ATTRIBUTE_SEALED) && !stack_slot_is_boxed_value (value)) {
+       if ((method->flags & METHOD_ATTRIBUTE_VIRTUAL) && !(method->flags & METHOD_ATTRIBUTE_FINAL) && !mono_class_is_sealed (method->klass) && !stack_slot_is_boxed_value (value)) {
                /*A stdarg 0 must not happen, we fail here only in fail fast mode to avoid double error reports*/
                if (IS_FAIL_FAST_MODE (ctx) && ctx->has_this_store)
                        CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid ldftn with virtual function in method with stdarg 0 at  0x%04x", ctx->ip_offset));
@@ -3166,7 +3166,7 @@ do_invoke_method (VerifyContext *ctx, int method_token, gboolean virtual_)
                if (method->flags & METHOD_ATTRIBUTE_ABSTRACT) 
                        CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Cannot use call with an abstract method at 0x%04x", ctx->ip_offset));
                
-               if ((method->flags & METHOD_ATTRIBUTE_VIRTUAL) && !(method->flags & METHOD_ATTRIBUTE_FINAL) && !(method->klass->flags & TYPE_ATTRIBUTE_SEALED)) {
+               if ((method->flags & METHOD_ATTRIBUTE_VIRTUAL) && !(method->flags & METHOD_ATTRIBUTE_FINAL) && !mono_class_is_sealed (method->klass)) {
                        virt_check_this = TRUE;
                        ctx->code [ctx->ip_offset].flags |= IL_CODE_CALL_NONFINAL_VIRTUAL;
                }
@@ -3811,7 +3811,7 @@ do_newobj (VerifyContext *ctx, int token)
                return;
        }
 
-       if (method->klass->flags & (TYPE_ATTRIBUTE_ABSTRACT | TYPE_ATTRIBUTE_INTERFACE))
+       if (mono_class_get_flags (method->klass) & (TYPE_ATTRIBUTE_ABSTRACT | TYPE_ATTRIBUTE_INTERFACE))
                CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Trying to instantiate an abstract or interface type at 0x%04x", ctx->ip_offset));
 
        if (!IS_SKIP_VISIBILITY (ctx) && !mono_method_can_access_method_full (ctx->method, method, NULL)) {
@@ -4643,7 +4643,7 @@ merge_stacks (VerifyContext *ctx, ILCodeDesc *from, ILCodeDesc *to, gboolean sta
                        }
 
                        /* if old class is an interface that new class implements */
-                       if (old_class->flags & TYPE_ATTRIBUTE_INTERFACE) {
+                       if (mono_class_is_interface (old_class)) {
                                if (verifier_class_is_assignable_from (old_class, new_class)) {
                                        match_class = old_class;
                                        goto match_found;       
@@ -4656,7 +4656,7 @@ merge_stacks (VerifyContext *ctx, ILCodeDesc *from, ILCodeDesc *to, gboolean sta
                                }
                        }
 
-                       if (new_class->flags & TYPE_ATTRIBUTE_INTERFACE) {
+                       if (mono_class_is_interface (new_class)) {
                                if (verifier_class_is_assignable_from (new_class, old_class)) {
                                        match_class = new_class;
                                        goto match_found;       
@@ -4848,7 +4848,7 @@ mono_method_verify (MonoMethod *method, int level)
                finish_collect_stats ();
                return ctx.list;
        }
-       if (!method->is_generic && !method->klass->is_generic && ctx.signature->has_type_parameters) {
+       if (!method->is_generic && !mono_class_is_gtd (method->klass) && ctx.signature->has_type_parameters) {
                ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Method and signature don't match in terms of genericity"));
                finish_collect_stats ();
                return ctx.list;
@@ -4895,11 +4895,11 @@ mono_method_verify (MonoMethod *method, int level)
        if (ctx.signature->is_inflated)
                ctx.generic_context = generic_context = mono_method_get_context (method);
 
-       if (!generic_context && (method->klass->generic_container || method->is_generic)) {
+       if (!generic_context && (mono_class_is_gtd (method->klass) || method->is_generic)) {
                if (method->is_generic)
                        ctx.generic_context = generic_context = &(mono_method_get_generic_container (method)->context);
                else
-                       ctx.generic_context = generic_context = &method->klass->generic_container->context;
+                       ctx.generic_context = generic_context = &mono_class_get_generic_container (method->klass)->context;
        }
 
        for (i = 0; i < ctx.num_locals; ++i) {
@@ -6102,7 +6102,7 @@ verify_class_for_overlapping_reference_fields (MonoClass *klass)
        MonoClassField *field;
        gboolean is_fulltrust = mono_verifier_is_class_full_trust (klass);
        /*We can't skip types with !has_references since this is calculated after we have run.*/
-       if (!((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT))
+       if (!mono_class_is_explicit_layout (klass))
                return TRUE;
 
 
@@ -6156,8 +6156,8 @@ verify_class_fields (MonoClass *klass)
        MonoClassField *field;
        MonoGenericContext *context = mono_class_get_context (klass);
        GHashTable *unique_fields = g_hash_table_new_full (&field_hash, &field_equals, NULL, NULL);
-       if (klass->generic_container)
-               context = &klass->generic_container->context;
+       if (mono_class_is_gtd (klass))
+               context = &mono_class_get_generic_container (klass)->context;
 
        while ((field = mono_class_get_fields (klass, &iter)) != NULL) {
                if (!mono_type_is_valid_type_in_context (field->type, context)) {
@@ -6180,7 +6180,7 @@ verify_interfaces (MonoClass *klass)
        int i;
        for (i = 0; i < klass->interface_count; ++i) {
                MonoClass *iface = klass->interfaces [i];
-               if (!(iface->flags & TYPE_ATTRIBUTE_INTERFACE))
+               if (!mono_class_get_flags (iface))
                        return FALSE;
        }
        return TRUE;
@@ -6259,7 +6259,7 @@ static gboolean
 verify_generic_parameters (MonoClass *klass)
 {
        int i;
-       MonoGenericContainer *gc = klass->generic_container;
+       MonoGenericContainer *gc = mono_class_get_generic_container (klass);
        MonoBitSet *used_args = mono_bitset_new (gc->type_argc, 0);
 
        for (i = 0; i < gc->type_argc; ++i) {
@@ -6284,7 +6284,7 @@ verify_generic_parameters (MonoClass *klass)
 
                        if (mono_type_is_generic_argument (constraint_type) && !recursive_mark_constraint_args (used_args, gc, constraint_type))
                                goto fail;
-                       if (ctr->generic_class && !mono_class_is_valid_generic_instantiation (NULL, ctr))
+                       if (mono_class_is_ginst (ctr) && !mono_class_is_valid_generic_instantiation (NULL, ctr))
                                goto fail;
                }
        }
@@ -6317,25 +6317,25 @@ mono_verifier_verify_class (MonoClass *klass)
        if (klass->parent) {
                if (MONO_CLASS_IS_INTERFACE (klass->parent))
                        return FALSE;
-               if (!klass->generic_class && klass->parent->generic_container)
+               if (!mono_class_is_ginst (klass) && mono_class_is_gtd (klass->parent))
                        return FALSE;
-               if (klass->parent->generic_class && !klass->generic_class) {
+               if (mono_class_is_ginst (klass->parent) && !mono_class_is_ginst (klass)) {
                        MonoGenericContext *context = mono_class_get_context (klass);
-                       if (klass->generic_container)
-                               context = &klass->generic_container->context;
+                       if (mono_class_is_gtd (klass))
+                               context = &mono_class_get_generic_container (klass)->context;
                        if (!mono_type_is_valid_type_in_context (&klass->parent->byval_arg, context))
                                return FALSE;
                }
        }
-       if (klass->generic_container && (klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT)
+       if (mono_class_is_gtd (klass) && (mono_class_is_explicit_layout (klass)))
                return FALSE;
-       if (klass->generic_container && !verify_generic_parameters (klass))
+       if (mono_class_is_gtd (klass) && !verify_generic_parameters (klass))
                return FALSE;
        if (!verify_class_for_overlapping_reference_fields (klass))
                return FALSE;
-       if (klass->generic_class && !mono_class_is_valid_generic_instantiation (NULL, klass))
+       if (mono_class_is_ginst (klass) && !mono_class_is_valid_generic_instantiation (NULL, klass))
                return FALSE;
-       if (klass->generic_class == NULL && !verify_class_fields (klass))
+       if (!mono_class_is_ginst (klass) && !verify_class_fields (klass))
                return FALSE;
        if (klass->valuetype && !verify_valuetype_layout (klass))
                return FALSE;
index 5644ce7d27b1eb708aa47933e1acca5b0be7b44d..35b6ce787cc48512909c48b617c326c650491bca 100644 (file)
@@ -12,7 +12,7 @@
 #include "w32handle-namespace.h"
 #include "mono/io-layer/io-layer.h"
 #include "mono/utils/mono-logger-internals.h"
-#include "mono/utils/w32handle.h"
+#include "mono/metadata/w32handle.h"
 
 typedef struct {
        gboolean manual;
index 5a2547774d49e6f80be7a883e4fa4f7a1cfa3956..75797a80d65e0fba735a99fad2b2b916d85bf9a6 100644 (file)
@@ -5,7 +5,7 @@
 #include <config.h>
 #include <glib.h>
 
-#include "mono/utils/w32handle.h"
+#include "mono/metadata/w32handle.h"
 
 #define MONO_W32HANDLE_NAMESPACE_MAX_PATH 260
 
diff --git a/mono/metadata/w32handle.c b/mono/metadata/w32handle.c
new file mode 100644 (file)
index 0000000..6e2a765
--- /dev/null
@@ -0,0 +1,1546 @@
+/*
+ * w32handle.c:  Generic and internal operations on handles
+ *
+ * Author:
+ *     Dick Porter (dick@ximian.com)
+ *     Ludovic Henry (luhenry@microsoft.com)
+ *
+ * (C) 2002-2011 Novell, Inc.
+ * Copyright 2011 Xamarin Inc
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+
+#include <config.h>
+
+#if !defined(HOST_WIN32)
+
+#include <glib.h>
+#include <pthread.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#include <string.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+#  include <sys/un.h>
+#endif
+#ifdef HAVE_SYS_MMAN_H
+#  include <sys/mman.h>
+#endif
+#ifdef HAVE_DIRENT_H
+#  include <dirent.h>
+#endif
+#include <sys/stat.h>
+#ifdef HAVE_SYS_RESOURCE_H
+#  include <sys/resource.h>
+#endif
+
+#include "w32handle.h"
+
+#include "utils/atomic.h"
+#include "utils/mono-logger-internals.h"
+#include "utils/mono-os-mutex.h"
+#include "utils/mono-proclib.h"
+#include "utils/mono-threads.h"
+#include "utils/mono-time.h"
+
+#undef DEBUG_REFS
+
+#define SLOT_MAX               (1024 * 16)
+
+/* must be a power of 2 */
+#define HANDLE_PER_SLOT        (256)
+
+#define INFINITE 0xFFFFFFFF
+
+typedef struct {
+       MonoW32HandleType type;
+       guint ref;
+       gboolean signalled;
+       mono_mutex_t signal_mutex;
+       mono_cond_t signal_cond;
+       gpointer specific;
+} MonoW32HandleBase;
+
+static MonoW32HandleCapability handle_caps [MONO_W32HANDLE_COUNT];
+static MonoW32HandleOps *handle_ops [MONO_W32HANDLE_COUNT];
+
+/*
+ * We can hold SLOT_MAX * HANDLE_PER_SLOT handles.
+ * If 4M handles are not enough... Oh, well... we will crash.
+ */
+#define SLOT_INDEX(x)  (x / HANDLE_PER_SLOT)
+#define SLOT_OFFSET(x) (x % HANDLE_PER_SLOT)
+
+static MonoW32HandleBase *private_handles [SLOT_MAX];
+static guint32 private_handles_count = 0;
+static guint32 private_handles_slots_count = 0;
+
+guint32 mono_w32handle_fd_reserve;
+
+/*
+ * This is an internal handle which is used for handling waiting for multiple handles.
+ * Threads which wait for multiple handles wait on this one handle, and when a handle
+ * is signalled, this handle is signalled too.
+ */
+static mono_mutex_t global_signal_mutex;
+static mono_cond_t global_signal_cond;
+
+static mono_mutex_t scan_mutex;
+
+static gboolean shutting_down = FALSE;
+
+static gboolean
+type_is_fd (MonoW32HandleType type)
+{
+       switch (type) {
+       case MONO_W32HANDLE_FILE:
+       case MONO_W32HANDLE_CONSOLE:
+       case MONO_W32HANDLE_SOCKET:
+       case MONO_W32HANDLE_PIPE:
+               return TRUE;
+       default:
+               return FALSE;
+       }
+}
+
+static gboolean
+mono_w32handle_lookup_data (gpointer handle, MonoW32HandleBase **handle_data)
+{
+       gsize index, offset;
+
+       g_assert (handle_data);
+
+       index = SLOT_INDEX ((gsize) handle);
+       if (index >= SLOT_MAX)
+               return FALSE;
+       if (!private_handles [index])
+               return FALSE;
+
+       offset = SLOT_OFFSET ((gsize) handle);
+       if (private_handles [index][offset].type == MONO_W32HANDLE_UNUSED)
+               return FALSE;
+
+       *handle_data = &private_handles [index][offset];
+       return TRUE;
+}
+
+MonoW32HandleType
+mono_w32handle_get_type (gpointer handle)
+{
+       MonoW32HandleBase *handle_data;
+
+       if (!mono_w32handle_lookup_data (handle, &handle_data))
+               return MONO_W32HANDLE_UNUSED;   /* An impossible type */
+
+       return handle_data->type;
+}
+
+void
+mono_w32handle_set_signal_state (gpointer handle, gboolean state, gboolean broadcast)
+{
+       MonoW32HandleBase *handle_data;
+
+       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+               return;
+       }
+
+#ifdef DEBUG
+       g_message ("%s: setting state of %p to %s (broadcast %s)", __func__,
+                  handle, state?"TRUE":"FALSE", broadcast?"TRUE":"FALSE");
+#endif
+
+       if (state == TRUE) {
+               /* Tell everyone blocking on a single handle */
+
+               /* The condition the global signal cond is waiting on is the signalling of
+                * _any_ handle. So lock it before setting the signalled state.
+                */
+               mono_os_mutex_lock (&global_signal_mutex);
+
+               /* This function _must_ be called with
+                * handle->signal_mutex locked
+                */
+               handle_data->signalled=state;
+
+               if (broadcast == TRUE) {
+                       mono_os_cond_broadcast (&handle_data->signal_cond);
+               } else {
+                       mono_os_cond_signal (&handle_data->signal_cond);
+               }
+
+               /* Tell everyone blocking on multiple handles that something
+                * was signalled
+                */
+               mono_os_cond_broadcast (&global_signal_cond);
+
+               mono_os_mutex_unlock (&global_signal_mutex);
+       } else {
+               handle_data->signalled=state;
+       }
+}
+
+gboolean
+mono_w32handle_issignalled (gpointer handle)
+{
+       MonoW32HandleBase *handle_data;
+
+       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+               return(FALSE);
+       }
+
+       return handle_data->signalled;
+}
+
+static int
+mono_w32handle_lock_signal_mutex (void)
+{
+#ifdef DEBUG
+       g_message ("%s: lock global signal mutex", __func__);
+#endif
+
+       mono_os_mutex_lock (&global_signal_mutex);
+
+       return 0;
+}
+
+static int
+mono_w32handle_unlock_signal_mutex (void)
+{
+#ifdef DEBUG
+       g_message ("%s: unlock global signal mutex", __func__);
+#endif
+
+       mono_os_mutex_unlock (&global_signal_mutex);
+
+       return 0;
+}
+
+int
+mono_w32handle_lock_handle (gpointer handle)
+{
+       MonoW32HandleBase *handle_data;
+
+#ifdef DEBUG
+       g_message ("%s: locking handle %p", __func__, handle);
+#endif
+
+       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+               return(0);
+       }
+
+       mono_w32handle_ref (handle);
+
+       mono_os_mutex_lock (&handle_data->signal_mutex);
+
+       return 0;
+}
+
+int
+mono_w32handle_trylock_handle (gpointer handle)
+{
+       MonoW32HandleBase *handle_data;
+       int ret;
+
+#ifdef DEBUG
+       g_message ("%s: locking handle %p", __func__, handle);
+#endif
+
+       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+               return(0);
+       }
+
+       mono_w32handle_ref (handle);
+
+       ret = mono_os_mutex_trylock (&handle_data->signal_mutex);
+       if (ret != 0) {
+               mono_w32handle_unref (handle);
+       }
+
+       return(ret);
+}
+
+int
+mono_w32handle_unlock_handle (gpointer handle)
+{
+       MonoW32HandleBase *handle_data;
+
+#ifdef DEBUG
+       g_message ("%s: unlocking handle %p", __func__, handle);
+#endif
+
+       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+               return(0);
+       }
+
+       mono_os_mutex_unlock (&handle_data->signal_mutex);
+
+       mono_w32handle_unref (handle);
+
+       return 0;
+}
+
+/*
+ * wapi_init:
+ *
+ *   Initialize the io-layer.
+ */
+void
+mono_w32handle_init (void)
+{
+       static gboolean initialized = FALSE;
+
+       if (initialized)
+               return;
+
+       g_assert ((sizeof (handle_ops) / sizeof (handle_ops[0]))
+                 == MONO_W32HANDLE_COUNT);
+
+       /* This is needed by the code in mono_w32handle_new_internal */
+       mono_w32handle_fd_reserve = (eg_getdtablesize () + (HANDLE_PER_SLOT - 1)) & ~(HANDLE_PER_SLOT - 1);
+
+       do {
+               /*
+                * The entries in private_handles reserved for fds are allocated lazily to
+                * save memory.
+                */
+
+               private_handles_count += HANDLE_PER_SLOT;
+               private_handles_slots_count ++;
+       } while(mono_w32handle_fd_reserve > private_handles_count);
+
+       mono_os_mutex_init (&scan_mutex);
+
+       mono_os_cond_init (&global_signal_cond);
+       mono_os_mutex_init (&global_signal_mutex);
+
+       initialized = TRUE;
+}
+
+void
+mono_w32handle_cleanup (void)
+{
+       int i, j, k;
+
+       g_assert (!shutting_down);
+       shutting_down = TRUE;
+
+       /* Every shared handle we were using ought really to be closed
+        * by now, but to make sure just blow them all away.  The
+        * exiting finalizer thread in particular races us to the
+        * program exit and doesn't always win, so it can be left
+        * cluttering up the shared file.  Anything else left over is
+        * really a bug.
+        */
+       for(i = SLOT_INDEX (0); private_handles[i] != NULL; i++) {
+               for(j = SLOT_OFFSET (0); j < HANDLE_PER_SLOT; j++) {
+                       MonoW32HandleBase *handle_data = &private_handles[i][j];
+                       gpointer handle = GINT_TO_POINTER (i*HANDLE_PER_SLOT+j);
+
+                       for(k = handle_data->ref; k > 0; k--) {
+                               mono_w32handle_unref (handle);
+                       }
+               }
+       }
+
+       for (i = 0; i < SLOT_MAX; ++i)
+               g_free (private_handles [i]);
+}
+
+static void mono_w32handle_init_handle (MonoW32HandleBase *handle,
+                              MonoW32HandleType type, gpointer handle_specific)
+{
+       g_assert (handle->ref == 0);
+
+       handle->type = type;
+       handle->signalled = FALSE;
+       handle->ref = 1;
+
+       mono_os_cond_init (&handle->signal_cond);
+       mono_os_mutex_init (&handle->signal_mutex);
+
+       if (handle_specific)
+               handle->specific = g_memdup (handle_specific, mono_w32handle_ops_typesize (type));
+}
+
+/*
+ * mono_w32handle_new_internal:
+ * @type: Init handle to this type
+ *
+ * Search for a free handle and initialize it. Return the handle on
+ * success and 0 on failure.  This is only called from
+ * mono_w32handle_new, and scan_mutex must be held.
+ */
+static guint32 mono_w32handle_new_internal (MonoW32HandleType type,
+                                         gpointer handle_specific)
+{
+       guint32 i, k, count;
+       static guint32 last = 0;
+       gboolean retry = FALSE;
+       
+       /* A linear scan should be fast enough.  Start from the last
+        * allocation, assuming that handles are allocated more often
+        * than they're freed. Leave the space reserved for file
+        * descriptors
+        */
+
+       if (last < mono_w32handle_fd_reserve) {
+               last = mono_w32handle_fd_reserve;
+       } else {
+               retry = TRUE;
+       }
+
+again:
+       count = last;
+       for(i = SLOT_INDEX (count); i < private_handles_slots_count; i++) {
+               if (private_handles [i]) {
+                       for (k = SLOT_OFFSET (count); k < HANDLE_PER_SLOT; k++) {
+                               MonoW32HandleBase *handle = &private_handles [i][k];
+
+                               if(handle->type == MONO_W32HANDLE_UNUSED) {
+                                       last = count + 1;
+
+                                       mono_w32handle_init_handle (handle, type, handle_specific);
+                                       return (count);
+                               }
+                               count++;
+                       }
+               }
+       }
+
+       if(retry && last > mono_w32handle_fd_reserve) {
+               /* Try again from the beginning */
+               last = mono_w32handle_fd_reserve;
+               goto again;
+       }
+
+       /* Will need to expand the array.  The caller will sort it out */
+
+       return(0);
+}
+
+gpointer
+mono_w32handle_new (MonoW32HandleType type, gpointer handle_specific)
+{
+       guint32 handle_idx = 0;
+       gpointer handle;
+
+       g_assert (!shutting_down);
+
+       g_assert(!type_is_fd(type));
+
+       mono_os_mutex_lock (&scan_mutex);
+
+       while ((handle_idx = mono_w32handle_new_internal (type, handle_specific)) == 0) {
+               /* Try and expand the array, and have another go */
+               int idx = SLOT_INDEX (private_handles_count);
+               if (idx >= SLOT_MAX) {
+                       break;
+               }
+
+               private_handles [idx] = g_new0 (MonoW32HandleBase, HANDLE_PER_SLOT);
+
+               private_handles_count += HANDLE_PER_SLOT;
+               private_handles_slots_count ++;
+       }
+
+       mono_os_mutex_unlock (&scan_mutex);
+
+       if (handle_idx == 0) {
+               /* We ran out of slots */
+               handle = INVALID_HANDLE_VALUE;
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: failed to create %s handle", __func__, mono_w32handle_ops_typename (type));
+               goto done;
+       }
+
+       /* Make sure we left the space for fd mappings */
+       g_assert (handle_idx >= mono_w32handle_fd_reserve);
+
+       handle = GUINT_TO_POINTER (handle_idx);
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: create %s handle %p", __func__, mono_w32handle_ops_typename (type), handle);
+
+done:
+       return(handle);
+}
+
+gpointer mono_w32handle_new_fd (MonoW32HandleType type, int fd,
+                             gpointer handle_specific)
+{
+       MonoW32HandleBase *handle_data;
+       int fd_index, fd_offset;
+
+       g_assert (!shutting_down);
+
+       g_assert(type_is_fd(type));
+
+       if (fd >= mono_w32handle_fd_reserve) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: failed to create %s handle, fd is too big", __func__, mono_w32handle_ops_typename (type));
+
+               return(GUINT_TO_POINTER (INVALID_HANDLE_VALUE));
+       }
+
+       fd_index = SLOT_INDEX (fd);
+       fd_offset = SLOT_OFFSET (fd);
+
+       /* Initialize the array entries on demand */
+       if (!private_handles [fd_index]) {
+               mono_os_mutex_lock (&scan_mutex);
+
+               if (!private_handles [fd_index])
+                       private_handles [fd_index] = g_new0 (MonoW32HandleBase, HANDLE_PER_SLOT);
+
+               mono_os_mutex_unlock (&scan_mutex);
+       }
+
+       handle_data = &private_handles [fd_index][fd_offset];
+
+       if (handle_data->type != MONO_W32HANDLE_UNUSED) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: failed to create %s handle, fd is already in use", __func__, mono_w32handle_ops_typename (type));
+               /* FIXME: clean up this handle?  We can't do anything
+                * with the fd, cos thats the new one
+                */
+               return(GUINT_TO_POINTER (INVALID_HANDLE_VALUE));
+       }
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: create %s handle %p", __func__, mono_w32handle_ops_typename (type), GUINT_TO_POINTER(fd));
+
+       mono_w32handle_init_handle (handle_data, type, handle_specific);
+
+       return(GUINT_TO_POINTER(fd));
+}
+
+gboolean
+mono_w32handle_lookup (gpointer handle, MonoW32HandleType type,
+                             gpointer *handle_specific)
+{
+       MonoW32HandleBase *handle_data;
+
+       g_assert (handle_specific);
+
+       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+               return(FALSE);
+       }
+
+       if (handle_data->type != type) {
+               return(FALSE);
+       }
+
+       *handle_specific = handle_data->specific;
+
+       return(TRUE);
+}
+
+static gboolean
+mono_w32handle_ref_core (gpointer handle, MonoW32HandleBase *handle_data);
+
+static gboolean
+mono_w32handle_unref_core (gpointer handle, MonoW32HandleBase *handle_data, guint minimum);
+
+void
+mono_w32handle_foreach (gboolean (*on_each)(gpointer handle, gpointer data, gpointer user_data), gpointer user_data)
+{
+       guint32 i, k;
+
+       mono_os_mutex_lock (&scan_mutex);
+
+       for (i = SLOT_INDEX (0); i < private_handles_slots_count; i++) {
+               if (!private_handles [i])
+                       continue;
+               for (k = SLOT_OFFSET (0); k < HANDLE_PER_SLOT; k++) {
+                       MonoW32HandleBase *handle_data = NULL;
+                       gpointer handle;
+                       gboolean destroy, finished;
+
+                       handle_data = &private_handles [i][k];
+                       if (handle_data->type == MONO_W32HANDLE_UNUSED)
+                               continue;
+
+                       handle = GUINT_TO_POINTER (i * HANDLE_PER_SLOT + k);
+
+                       if (!mono_w32handle_ref_core (handle, handle_data)) {
+                               /* we are racing with mono_w32handle_unref:
+                                *  the handle ref has been decremented, but it
+                                *  hasn't yet been destroyed. */
+                               continue;
+                       }
+
+                       finished = on_each (handle, handle_data->specific, user_data);
+
+                       /* we do not want to have to destroy the handle here,
+                        * as it would means the ref/unref are unbalanced */
+                       destroy = mono_w32handle_unref_core (handle, handle_data, 2);
+                       g_assert (!destroy);
+
+                       if (finished)
+                               goto done;
+               }
+       }
+
+done:
+       mono_os_mutex_unlock (&scan_mutex);
+}
+
+typedef struct {
+       MonoW32HandleType type;
+       gboolean (*search_user_callback)(gpointer handle, gpointer data);
+       gpointer search_user_data;
+       gpointer handle;
+       gpointer handle_specific;
+} SearchData;
+
+static gboolean
+search_callback (gpointer handle, gpointer handle_specific, gpointer user_data)
+{
+       SearchData *search_data = (SearchData*) user_data;
+
+       if (search_data->type != mono_w32handle_get_type (handle))
+               return FALSE;
+
+       if (!search_data->search_user_callback (handle, search_data->search_user_data))
+               return FALSE;
+
+       mono_w32handle_ref (handle);
+       search_data->handle = handle;
+       search_data->handle_specific = handle_specific;
+       return TRUE;
+}
+
+/* This might list some shared handles twice if they are already
+ * opened by this process, and the check function returns FALSE the
+ * first time.  Shared handles that are created during the search are
+ * unreffed if the check function returns FALSE, so callers must not
+ * rely on the handle persisting (unless the check function returns
+ * TRUE)
+ * The caller owns the returned handle.
+ */
+gpointer mono_w32handle_search (MonoW32HandleType type,
+                             gboolean (*check)(gpointer test, gpointer user),
+                             gpointer user_data,
+                             gpointer *handle_specific,
+                             gboolean search_shared)
+{
+       SearchData search_data;
+
+       memset (&search_data, 0, sizeof (search_data));
+       search_data.type = type;
+       search_data.search_user_callback = check;
+       search_data.search_user_data = user_data;
+       mono_w32handle_foreach (search_callback, &search_data);
+       if (handle_specific)
+               *handle_specific = search_data.handle_specific;
+       return search_data.handle;
+}
+
+static gboolean
+mono_w32handle_ref_core (gpointer handle, MonoW32HandleBase *handle_data)
+{
+       guint old, new;
+
+       do {
+               old = handle_data->ref;
+               if (old == 0)
+                       return FALSE;
+
+               new = old + 1;
+       } while (InterlockedCompareExchange ((gint32*) &handle_data->ref, new, old) != old);
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: ref %s handle %p, ref: %d -> %d",
+               __func__, mono_w32handle_ops_typename (handle_data->type), handle, old, new);
+
+       return TRUE;
+}
+
+static gboolean
+mono_w32handle_unref_core (gpointer handle, MonoW32HandleBase *handle_data, guint minimum)
+{
+       MonoW32HandleType type;
+       guint old, new;
+
+       type = handle_data->type;
+
+       do {
+               old = handle_data->ref;
+               if (!(old >= minimum))
+                       g_error ("%s: handle %p has ref %d, it should be >= %d", __func__, handle, old, minimum);
+
+               new = old - 1;
+       } while (InterlockedCompareExchange ((gint32*) &handle_data->ref, new, old) != old);
+
+       /* handle_data might contain invalid data from now on, if
+        * another thread is unref'ing this handle at the same time */
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: unref %s handle %p, ref: %d -> %d destroy: %s",
+               __func__, mono_w32handle_ops_typename (type), handle, old, new, new == 0 ? "true" : "false");
+
+       return new == 0;
+}
+
+void mono_w32handle_ref (gpointer handle)
+{
+       MonoW32HandleBase *handle_data;
+
+       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: failed to ref handle %p, unknown handle", __func__, handle);
+               return;
+       }
+
+       if (!mono_w32handle_ref_core (handle, handle_data))
+               g_error ("%s: failed to ref handle %p", __func__, handle);
+}
+
+static void (*_wapi_handle_ops_get_close_func (MonoW32HandleType type))(gpointer, gpointer);
+
+/* The handle must not be locked on entry to this function */
+void
+mono_w32handle_unref (gpointer handle)
+{
+       MonoW32HandleBase *handle_data;
+       gboolean destroy;
+
+       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: failed to unref handle %p, unknown handle",
+                       __func__, handle);
+               return;
+       }
+
+       destroy = mono_w32handle_unref_core (handle, handle_data, 1);
+
+       if (destroy) {
+               /* Need to copy the handle info, reset the slot in the
+                * array, and _only then_ call the close function to
+                * avoid race conditions (eg file descriptors being
+                * closed, and another file being opened getting the
+                * same fd racing the memset())
+                */
+               MonoW32HandleType type;
+               gpointer handle_specific;
+               void (*close_func)(gpointer, gpointer);
+
+               type = handle_data->type;
+               handle_specific = handle_data->specific;
+
+               mono_os_mutex_lock (&scan_mutex);
+
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: destroy %s handle %p", __func__, mono_w32handle_ops_typename (type), handle);
+
+               mono_os_mutex_destroy (&handle_data->signal_mutex);
+               mono_os_cond_destroy (&handle_data->signal_cond);
+
+               memset (handle_data, 0, sizeof (MonoW32HandleBase));
+
+               mono_os_mutex_unlock (&scan_mutex);
+
+               close_func = _wapi_handle_ops_get_close_func (type);
+               if (close_func != NULL) {
+                       close_func (handle, handle_specific);
+               }
+
+               g_free (handle_specific);
+       }
+}
+
+void
+mono_w32handle_register_ops (MonoW32HandleType type, MonoW32HandleOps *ops)
+{
+       handle_ops [type] = ops;
+}
+
+void mono_w32handle_register_capabilities (MonoW32HandleType type,
+                                        MonoW32HandleCapability caps)
+{
+       handle_caps[type] = caps;
+}
+
+gboolean mono_w32handle_test_capabilities (gpointer handle,
+                                        MonoW32HandleCapability caps)
+{
+       MonoW32HandleBase *handle_data;
+       MonoW32HandleType type;
+
+       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+               return(FALSE);
+       }
+
+       type = handle_data->type;
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: testing 0x%x against 0x%x (%d)", __func__,
+                  handle_caps[type], caps, handle_caps[type] & caps);
+
+       return((handle_caps[type] & caps) != 0);
+}
+
+static void (*_wapi_handle_ops_get_close_func (MonoW32HandleType type))(gpointer, gpointer)
+{
+       if (handle_ops[type] != NULL &&
+           handle_ops[type]->close != NULL) {
+               return (handle_ops[type]->close);
+       }
+
+       return (NULL);
+}
+
+void mono_w32handle_ops_close (gpointer handle, gpointer data)
+{
+       MonoW32HandleBase *handle_data;
+       MonoW32HandleType type;
+
+       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+               return;
+       }
+
+       type = handle_data->type;
+
+       if (handle_ops[type] != NULL &&
+           handle_ops[type]->close != NULL) {
+               handle_ops[type]->close (handle, data);
+       }
+}
+
+void mono_w32handle_ops_details (MonoW32HandleType type, gpointer data)
+{
+       if (handle_ops[type] != NULL &&
+           handle_ops[type]->details != NULL) {
+               handle_ops[type]->details (data);
+       }
+}
+
+const gchar* mono_w32handle_ops_typename (MonoW32HandleType type)
+{
+       g_assert (handle_ops [type]);
+       g_assert (handle_ops [type]->typename);
+       return handle_ops [type]->typename ();
+}
+
+gsize mono_w32handle_ops_typesize (MonoW32HandleType type)
+{
+       g_assert (handle_ops [type]);
+       g_assert (handle_ops [type]->typesize);
+       return handle_ops [type]->typesize ();
+}
+
+void mono_w32handle_ops_signal (gpointer handle)
+{
+       MonoW32HandleBase *handle_data;
+       MonoW32HandleType type;
+
+       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+               return;
+       }
+
+       type = handle_data->type;
+
+       if (handle_ops[type] != NULL && handle_ops[type]->signal != NULL) {
+               handle_ops[type]->signal (handle);
+       }
+}
+
+gboolean mono_w32handle_ops_own (gpointer handle, guint32 *statuscode)
+{
+       MonoW32HandleBase *handle_data;
+       MonoW32HandleType type;
+
+       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+               return(FALSE);
+       }
+
+       type = handle_data->type;
+
+       if (handle_ops[type] != NULL && handle_ops[type]->own_handle != NULL) {
+               return(handle_ops[type]->own_handle (handle, statuscode));
+       } else {
+               return(FALSE);
+       }
+}
+
+gboolean mono_w32handle_ops_isowned (gpointer handle)
+{
+       MonoW32HandleBase *handle_data;
+       MonoW32HandleType type;
+
+       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+               return(FALSE);
+       }
+
+       type = handle_data->type;
+
+       if (handle_ops[type] != NULL && handle_ops[type]->is_owned != NULL) {
+               return(handle_ops[type]->is_owned (handle));
+       } else {
+               return(FALSE);
+       }
+}
+
+guint32 mono_w32handle_ops_specialwait (gpointer handle, guint32 timeout, gboolean *alerted)
+{
+       MonoW32HandleBase *handle_data;
+       MonoW32HandleType type;
+
+       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+               return(WAIT_FAILED);
+       }
+
+       type = handle_data->type;
+
+       if (handle_ops[type] != NULL &&
+           handle_ops[type]->special_wait != NULL) {
+               return(handle_ops[type]->special_wait (handle, timeout, alerted));
+       } else {
+               return(WAIT_FAILED);
+       }
+}
+
+void mono_w32handle_ops_prewait (gpointer handle)
+{
+       MonoW32HandleBase *handle_data;
+       MonoW32HandleType type;
+
+       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+               return;
+       }
+
+       type = handle_data->type;
+
+       if (handle_ops[type] != NULL &&
+           handle_ops[type]->prewait != NULL) {
+               handle_ops[type]->prewait (handle);
+       }
+}
+
+static void
+spin (guint32 ms)
+{
+       struct timespec sleepytime;
+
+       g_assert (ms < 1000);
+
+       sleepytime.tv_sec = 0;
+       sleepytime.tv_nsec = ms * 1000000;
+       nanosleep (&sleepytime, NULL);
+}
+
+static void
+mono_w32handle_lock_handles (gpointer *handles, gsize numhandles)
+{
+       guint32 i, iter=0;
+       int thr_ret;
+
+       /* Lock all the handles, with backoff */
+again:
+       for(i=0; i<numhandles; i++) {
+               gpointer handle = handles[i];
+
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: attempting to lock %p", __func__, handle);
+
+               thr_ret = mono_w32handle_trylock_handle (handle);
+
+               if (thr_ret != 0) {
+                       /* Bummer */
+
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: attempt failed for %p: %s", __func__,
+                                  handle, strerror (thr_ret));
+
+                       while (i--) {
+                               handle = handles[i];
+
+                               thr_ret = mono_w32handle_unlock_handle (handle);
+                               g_assert (thr_ret == 0);
+                       }
+
+                       /* If iter ever reaches 100 the nanosleep will
+                        * return EINVAL immediately, but we have a
+                        * design flaw if that happens.
+                        */
+                       iter++;
+                       if(iter==100) {
+                               g_warning ("%s: iteration overflow!",
+                                          __func__);
+                               iter=1;
+                       }
+
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Backing off for %d ms", __func__,
+                                  iter*10);
+                       spin (10 * iter);
+
+                       goto again;
+               }
+       }
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Locked all handles", __func__);
+}
+
+static void
+mono_w32handle_unlock_handles (gpointer *handles, gsize numhandles)
+{
+       guint32 i;
+       int thr_ret;
+
+       for(i=0; i<numhandles; i++) {
+               gpointer handle = handles[i];
+
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: unlocking handle %p", __func__, handle);
+
+               thr_ret = mono_w32handle_unlock_handle (handle);
+               g_assert (thr_ret == 0);
+       }
+}
+
+static int
+mono_w32handle_timedwait_signal_naked (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout, gboolean poll, gboolean *alerted)
+{
+       int res;
+
+       if (!poll) {
+               res = mono_os_cond_timedwait (cond, mutex, timeout);
+       } else {
+               /* This is needed when waiting for process handles */
+               if (!alerted) {
+                       /*
+                        * pthread_cond_(timed)wait() can return 0 even if the condition was not
+                        * signalled.  This happens at least on Darwin.  We surface this, i.e., we
+                        * get spurious wake-ups.
+                        *
+                        * http://pubs.opengroup.org/onlinepubs/007908775/xsh/pthread_cond_wait.html
+                        */
+                       res = mono_os_cond_timedwait (cond, mutex, timeout);
+               } else {
+                       if (timeout < 100) {
+                               /* Real timeout is less than 100ms time */
+                               res = mono_os_cond_timedwait (cond, mutex, timeout);
+                       } else {
+                               res = mono_os_cond_timedwait (cond, mutex, 100);
+
+                               /* Mask the fake timeout, this will cause
+                                * another poll if the cond was not really signaled
+                                */
+                               if (res == -1)
+                                       res = 0;
+                       }
+               }
+       }
+
+       return res;
+}
+
+static void
+signal_global (gpointer unused)
+{
+       /* If we reach here, then interrupt token is set to the flag value, which
+        * means that the target thread is either
+        * - before the first CAS in timedwait, which means it won't enter the wait.
+        * - it is after the first CAS, so it is already waiting, or it will enter
+        *    the wait, and it will be interrupted by the broadcast. */
+       mono_os_mutex_lock (&global_signal_mutex);
+       mono_os_cond_broadcast (&global_signal_cond);
+       mono_os_mutex_unlock (&global_signal_mutex);
+}
+
+static int
+mono_w32handle_timedwait_signal (guint32 timeout, gboolean poll, gboolean *alerted)
+{
+       int res;
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: waiting for global", __func__);
+
+       if (alerted)
+               *alerted = FALSE;
+
+       if (alerted) {
+               mono_thread_info_install_interrupt (signal_global, NULL, alerted);
+               if (*alerted)
+                       return 0;
+       }
+
+       res = mono_w32handle_timedwait_signal_naked (&global_signal_cond, &global_signal_mutex, timeout, poll, alerted);
+
+       if (alerted)
+               mono_thread_info_uninstall_interrupt (alerted);
+
+       return res;
+}
+
+static void
+signal_handle_and_unref (gpointer handle)
+{
+       MonoW32HandleBase *handle_data;
+       mono_cond_t *cond;
+       mono_mutex_t *mutex;
+
+       if (!mono_w32handle_lookup_data (handle, &handle_data))
+               g_error ("cannot signal unknown handle %p", handle);
+
+       /* If we reach here, then interrupt token is set to the flag value, which
+        * means that the target thread is either
+        * - before the first CAS in timedwait, which means it won't enter the wait.
+        * - it is after the first CAS, so it is already waiting, or it will enter
+        *    the wait, and it will be interrupted by the broadcast. */
+       cond = &handle_data->signal_cond;
+       mutex = &handle_data->signal_mutex;
+
+       mono_os_mutex_lock (mutex);
+       mono_os_cond_broadcast (cond);
+       mono_os_mutex_unlock (mutex);
+
+       mono_w32handle_unref (handle);
+}
+
+static int
+mono_w32handle_timedwait_signal_handle (gpointer handle, guint32 timeout, gboolean poll, gboolean *alerted)
+{
+       MonoW32HandleBase *handle_data;
+       int res;
+
+       if (!mono_w32handle_lookup_data (handle, &handle_data))
+               g_error ("cannot wait on unknown handle %p", handle);
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: waiting for %p (type %s)", __func__, handle,
+                  mono_w32handle_ops_typename (mono_w32handle_get_type (handle)));
+
+       if (alerted)
+               *alerted = FALSE;
+
+       if (alerted) {
+               mono_thread_info_install_interrupt (signal_handle_and_unref, handle, alerted);
+               if (*alerted)
+                       return 0;
+               mono_w32handle_ref (handle);
+       }
+
+       res = mono_w32handle_timedwait_signal_naked (&handle_data->signal_cond, &handle_data->signal_mutex, timeout, poll, alerted);
+
+       if (alerted) {
+               mono_thread_info_uninstall_interrupt (alerted);
+               if (!*alerted) {
+                       /* if it is alerted, then the handle is unref in the interrupt callback */
+                       mono_w32handle_unref (handle);
+               }
+       }
+
+       return res;
+}
+
+static gboolean
+dump_callback (gpointer handle, gpointer handle_specific, gpointer user_data)
+{
+       MonoW32HandleBase *handle_data;
+
+       if (!mono_w32handle_lookup_data (handle, &handle_data))
+               g_error ("cannot dump unknown handle %p", handle);
+
+       g_print ("%p [%7s] signalled: %5s ref: %3d ",
+               handle, mono_w32handle_ops_typename (handle_data->type), handle_data->signalled ? "true" : "false", handle_data->ref);
+       mono_w32handle_ops_details (handle_data->type, handle_data->specific);
+       g_print ("\n");
+
+       return FALSE;
+}
+
+void mono_w32handle_dump (void)
+{
+       mono_w32handle_foreach (dump_callback, NULL);
+}
+
+static gboolean
+own_if_signalled (gpointer handle, guint32 *statuscode)
+{
+       if (!mono_w32handle_issignalled (handle))
+               return FALSE;
+
+       *statuscode = WAIT_OBJECT_0;
+       mono_w32handle_ops_own (handle, statuscode);
+       return TRUE;
+}
+
+static gboolean
+own_if_owned( gpointer handle, guint32 *statuscode)
+{
+       if (!mono_w32handle_ops_isowned (handle))
+               return FALSE;
+
+       *statuscode = WAIT_OBJECT_0;
+       mono_w32handle_ops_own (handle, statuscode);
+       return TRUE;
+}
+
+MonoW32HandleWaitRet
+mono_w32handle_wait_one (gpointer handle, guint32 timeout, gboolean alertable)
+{
+       MonoW32HandleWaitRet ret;
+       gboolean alerted;
+       gint64 start;
+       gint thr_ret;
+       guint32 statuscode = 0;
+
+       alerted = FALSE;
+
+       if (mono_w32handle_test_capabilities (handle, MONO_W32HANDLE_CAP_SPECIAL_WAIT)) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p has special wait",
+                       __func__, handle);
+
+               switch (mono_w32handle_ops_specialwait (handle, timeout, alertable ? &alerted : NULL)) {
+               case WAIT_OBJECT_0:
+                       ret = MONO_W32HANDLE_WAIT_RET_SUCCESS_0;
+                       break;
+               case WAIT_ABANDONED_0:
+                       ret = MONO_W32HANDLE_WAIT_RET_ABANDONED_0;
+                       break;
+               case WAIT_IO_COMPLETION:
+                       ret = MONO_W32HANDLE_WAIT_RET_ALERTED;
+                       break;
+               case WAIT_TIMEOUT:
+                       ret = MONO_W32HANDLE_WAIT_RET_TIMEOUT;
+                       break;
+               case WAIT_FAILED:
+                       ret = MONO_W32HANDLE_WAIT_RET_FAILED;
+                       break;
+               default:
+                       g_assert_not_reached ();
+               }
+
+               if (alerted)
+                       ret = MONO_W32HANDLE_WAIT_RET_ALERTED;
+
+               return ret;
+       }
+
+       if (!mono_w32handle_test_capabilities (handle, MONO_W32HANDLE_CAP_WAIT)) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p can't be waited for",
+                       __func__, handle);
+
+               return MONO_W32HANDLE_WAIT_RET_FAILED;
+       }
+
+       thr_ret = mono_w32handle_lock_handle (handle);
+       g_assert (thr_ret == 0);
+
+       if (mono_w32handle_test_capabilities (handle, MONO_W32HANDLE_CAP_OWN)) {
+               if (own_if_owned (handle, &statuscode)) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p already owned",
+                               __func__, handle);
+
+                       ret = statuscode == WAIT_ABANDONED_0 ? MONO_W32HANDLE_WAIT_RET_ABANDONED_0 : MONO_W32HANDLE_WAIT_RET_SUCCESS_0;
+                       goto done;
+               }
+       }
+
+       if (timeout != INFINITE)
+               start = mono_msec_ticks ();
+
+       for (;;) {
+               gint waited;
+
+               if (own_if_signalled (handle, &statuscode)) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p signalled",
+                               __func__, handle);
+
+                       ret = statuscode == WAIT_ABANDONED_0 ? MONO_W32HANDLE_WAIT_RET_ABANDONED_0 : MONO_W32HANDLE_WAIT_RET_SUCCESS_0;
+                       goto done;
+               }
+
+               mono_w32handle_ops_prewait (handle);
+
+               if (timeout == INFINITE) {
+                       waited = mono_w32handle_timedwait_signal_handle (handle, INFINITE, FALSE, alertable ? &alerted : NULL);
+               } else {
+                       gint64 elapsed;
+
+                       elapsed = mono_msec_ticks () - start;
+                       if (elapsed > timeout) {
+                               ret = MONO_W32HANDLE_WAIT_RET_TIMEOUT;
+                               goto done;
+                       }
+
+                       waited = mono_w32handle_timedwait_signal_handle (handle, timeout - elapsed, FALSE, alertable ? &alerted : NULL);
+               }
+
+               if (alerted) {
+                       ret = MONO_W32HANDLE_WAIT_RET_ALERTED;
+                       goto done;
+               }
+
+               if (waited != 0) {
+                       ret = MONO_W32HANDLE_WAIT_RET_TIMEOUT;
+                       goto done;
+               }
+       }
+
+done:
+       thr_ret = mono_w32handle_unlock_handle (handle);
+       g_assert (thr_ret == 0);
+
+       return ret;
+}
+
+MonoW32HandleWaitRet
+mono_w32handle_wait_multiple (gpointer *handles, gsize nhandles, gboolean waitall, guint32 timeout, gboolean alertable)
+{
+       MonoW32HandleWaitRet ret;
+       gboolean alerted, poll;
+       gint i, thr_ret;
+       gint64 start;
+       gpointer handles_sorted [MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS];
+       guint32 statuscodes [MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS] = {0};
+
+       if (nhandles == 0)
+               return MONO_W32HANDLE_WAIT_RET_FAILED;
+
+       if (nhandles == 1)
+               return mono_w32handle_wait_one (handles [0], timeout, alertable);
+
+       alerted = FALSE;
+
+       if (nhandles > MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: too many handles: %zd",
+                       __func__, nhandles);
+
+               return MONO_W32HANDLE_WAIT_RET_FAILED;
+       }
+
+       for (i = 0; i < nhandles; ++i) {
+               if (!mono_w32handle_test_capabilities (handles[i], MONO_W32HANDLE_CAP_WAIT)
+                        && !mono_w32handle_test_capabilities (handles[i], MONO_W32HANDLE_CAP_SPECIAL_WAIT))
+               {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p can't be waited for",
+                                  __func__, handles [i]);
+
+                       return MONO_W32HANDLE_WAIT_RET_FAILED;
+               }
+
+               handles_sorted [i] = handles [i];
+       }
+
+       qsort (handles_sorted, nhandles, sizeof (gpointer), g_direct_equal);
+       for (i = 1; i < nhandles; ++i) {
+               if (handles_sorted [i - 1] == handles_sorted [i]) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p is duplicated",
+                               __func__, handles_sorted [i]);
+
+                       return MONO_W32HANDLE_WAIT_RET_FAILED;
+               }
+       }
+
+       poll = FALSE;
+       for (i = 0; i < nhandles; ++i) {
+               if (mono_w32handle_get_type (handles [i]) == MONO_W32HANDLE_PROCESS) {
+                       /* Can't wait for a process handle + another handle without polling */
+                       poll = TRUE;
+               }
+       }
+
+       if (timeout != INFINITE)
+               start = mono_msec_ticks ();
+
+       for (i = 0; i < nhandles; ++i) {
+               /* Add a reference, as we need to ensure the handle wont
+                * disappear from under us while we're waiting in the loop
+                * (not lock, as we don't want exclusive access here) */
+               mono_w32handle_ref (handles [i]);
+       }
+
+       for (;;) {
+               gsize count, lowest;
+               gboolean signalled;
+               gint waited;
+
+               count = 0;
+               lowest = nhandles;
+
+               mono_w32handle_lock_handles (handles, nhandles);
+
+               for (i = 0; i < nhandles; i++) {
+                       if ((mono_w32handle_test_capabilities (handles [i], MONO_W32HANDLE_CAP_OWN) && mono_w32handle_ops_isowned (handles [i]))
+                                || mono_w32handle_issignalled (handles [i]))
+                       {
+                               count ++;
+
+                               if (i < lowest)
+                                       lowest = i;
+                       }
+               }
+
+               signalled = (waitall && count == nhandles) || (!waitall && count > 0);
+
+               if (signalled) {
+                       for (i = 0; i < nhandles; i++)
+                               own_if_signalled (handles [i], &statuscodes [i]);
+               }
+
+               mono_w32handle_unlock_handles (handles, nhandles);
+
+               if (signalled) {
+                       ret = MONO_W32HANDLE_WAIT_RET_SUCCESS_0 + lowest;
+                       for (i = lowest; i < nhandles; i++) {
+                               if (statuscodes [i] == WAIT_ABANDONED_0) {
+                                       ret = MONO_W32HANDLE_WAIT_RET_ABANDONED_0 + lowest;
+                                       break;
+                               }
+                       }
+                       goto done;
+               }
+
+               for (i = 0; i < nhandles; i++) {
+                       mono_w32handle_ops_prewait (handles[i]);
+
+                       if (mono_w32handle_test_capabilities (handles [i], MONO_W32HANDLE_CAP_SPECIAL_WAIT)
+                                && !mono_w32handle_issignalled (handles [i]))
+                       {
+                               mono_w32handle_ops_specialwait (handles [i], 0, alertable ? &alerted : NULL);
+                       }
+               }
+
+               thr_ret = mono_w32handle_lock_signal_mutex ();
+               g_assert (thr_ret == 0);
+
+               if (waitall) {
+                       signalled = TRUE;
+                       for (i = 0; i < nhandles; ++i) {
+                               if (!mono_w32handle_issignalled (handles [i])) {
+                                       signalled = FALSE;
+                                       break;
+                               }
+                       }
+               } else {
+                       signalled = FALSE;
+                       for (i = 0; i < nhandles; ++i) {
+                               if (mono_w32handle_issignalled (handles [i])) {
+                                       signalled = TRUE;
+                                       break;
+                               }
+                       }
+               }
+
+               waited = 0;
+
+               if (!signalled) {
+                       if (timeout == INFINITE) {
+                               waited = mono_w32handle_timedwait_signal (INFINITE, poll, alertable ? &alerted : NULL);
+                       } else {
+                               gint64 elapsed;
+
+                               elapsed = mono_msec_ticks () - start;
+                               if (elapsed > timeout) {
+                                       ret = MONO_W32HANDLE_WAIT_RET_TIMEOUT;
+
+                                       thr_ret = mono_w32handle_unlock_signal_mutex ();
+                                       g_assert (thr_ret == 0);
+
+                                       goto done;
+                               }
+
+                               waited = mono_w32handle_timedwait_signal (timeout - elapsed, poll, alertable ? &alerted : NULL);
+                       }
+               }
+
+               thr_ret = mono_w32handle_unlock_signal_mutex ();
+               g_assert (thr_ret == 0);
+
+               if (alerted) {
+                       ret = MONO_W32HANDLE_WAIT_RET_ALERTED;
+                       goto done;
+               }
+
+               if (waited != 0) {
+                       ret = MONO_W32HANDLE_WAIT_RET_TIMEOUT;
+                       goto done;
+               }
+       }
+
+done:
+       for (i = 0; i < nhandles; i++) {
+               /* Unref everything we reffed above */
+               mono_w32handle_unref (handles [i]);
+       }
+
+       return ret;
+}
+
+MonoW32HandleWaitRet
+mono_w32handle_signal_and_wait (gpointer signal_handle, gpointer wait_handle, guint32 timeout, gboolean alertable)
+{
+       MonoW32HandleWaitRet ret;
+       gint64 start;
+       gboolean alerted;
+       gint thr_ret;
+       guint32 statuscode = 0;
+
+       alerted = FALSE;
+
+       if (!mono_w32handle_test_capabilities (signal_handle, MONO_W32HANDLE_CAP_SIGNAL))
+               return MONO_W32HANDLE_WAIT_RET_FAILED;
+       if (!mono_w32handle_test_capabilities (wait_handle, MONO_W32HANDLE_CAP_WAIT))
+               return MONO_W32HANDLE_WAIT_RET_FAILED;
+
+       if (mono_w32handle_test_capabilities (wait_handle, MONO_W32HANDLE_CAP_SPECIAL_WAIT)) {
+               g_warning ("%s: handle %p has special wait, implement me!!", __func__, wait_handle);
+               return MONO_W32HANDLE_WAIT_RET_FAILED;
+       }
+
+       thr_ret = mono_w32handle_lock_handle (wait_handle);
+       g_assert (thr_ret == 0);
+
+       mono_w32handle_ops_signal (signal_handle);
+
+       if (mono_w32handle_test_capabilities (wait_handle, MONO_W32HANDLE_CAP_OWN)) {
+               if (own_if_owned (wait_handle, &statuscode)) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p already owned",
+                               __func__, wait_handle);
+
+                       ret = statuscode == WAIT_ABANDONED_0 ? MONO_W32HANDLE_WAIT_RET_ABANDONED_0 : MONO_W32HANDLE_WAIT_RET_SUCCESS_0;
+                       goto done;
+               }
+       }
+
+       if (timeout != INFINITE)
+               start = mono_msec_ticks ();
+
+       for (;;) {
+               gint waited;
+
+               if (own_if_signalled (wait_handle, &statuscode)) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p signalled",
+                               __func__, wait_handle);
+
+                       ret = statuscode == WAIT_ABANDONED_0 ? MONO_W32HANDLE_WAIT_RET_ABANDONED_0 : MONO_W32HANDLE_WAIT_RET_SUCCESS_0;
+                       goto done;
+               }
+
+               mono_w32handle_ops_prewait (wait_handle);
+
+               if (timeout == INFINITE) {
+                       waited = mono_w32handle_timedwait_signal_handle (wait_handle, INFINITE, FALSE, alertable ? &alerted : NULL);
+               } else {
+                       gint64 elapsed;
+
+                       elapsed = mono_msec_ticks () - start;
+                       if (elapsed > timeout) {
+                               ret = MONO_W32HANDLE_WAIT_RET_TIMEOUT;
+                               goto done;
+                       }
+
+                       waited = mono_w32handle_timedwait_signal_handle (wait_handle, timeout - elapsed, FALSE, alertable ? &alerted : NULL);
+               }
+
+               if (alerted) {
+                       ret = MONO_W32HANDLE_WAIT_RET_ALERTED;
+                       goto done;
+               }
+
+               if (waited != 0) {
+                       ret = MONO_W32HANDLE_WAIT_RET_TIMEOUT;
+                       goto done;
+               }
+       }
+
+done:
+       thr_ret = mono_w32handle_unlock_handle (wait_handle);
+       g_assert (thr_ret == 0);
+
+       return ret;
+}
+
+#endif /* !defined(HOST_WIN32) */
diff --git a/mono/metadata/w32handle.h b/mono/metadata/w32handle.h
new file mode 100644 (file)
index 0000000..92cf87b
--- /dev/null
@@ -0,0 +1,186 @@
+
+#ifndef _MONO_METADATA_W32HANDLE_H_
+#define _MONO_METADATA_W32HANDLE_H_
+
+#include <config.h>
+#include <glib.h>
+
+#ifndef INVALID_HANDLE_VALUE
+#define INVALID_HANDLE_VALUE (gpointer)-1
+#endif
+
+#define MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS 64
+
+typedef enum {
+       MONO_W32HANDLE_UNUSED = 0,
+       MONO_W32HANDLE_FILE,
+       MONO_W32HANDLE_CONSOLE,
+       MONO_W32HANDLE_THREAD,
+       MONO_W32HANDLE_SEM,
+       MONO_W32HANDLE_MUTEX,
+       MONO_W32HANDLE_EVENT,
+       MONO_W32HANDLE_SOCKET,
+       MONO_W32HANDLE_FIND,
+       MONO_W32HANDLE_PROCESS,
+       MONO_W32HANDLE_PIPE,
+       MONO_W32HANDLE_NAMEDMUTEX,
+       MONO_W32HANDLE_NAMEDSEM,
+       MONO_W32HANDLE_NAMEDEVENT,
+       MONO_W32HANDLE_COUNT
+} MonoW32HandleType;
+
+typedef struct 
+{
+       void (*close)(gpointer handle, gpointer data);
+
+       /* SignalObjectAndWait */
+       void (*signal)(gpointer signal);
+
+       /* Called by WaitForSingleObject and WaitForMultipleObjects,
+        * with the handle locked (shared handles aren't locked.)
+        * Returns TRUE if ownership was established, false otherwise.
+        * If TRUE, *statuscode contains a status code such as
+        * WAIT_OBJECT_0 or WAIT_ABANDONED_0.
+        */
+       gboolean (*own_handle)(gpointer handle, guint32 *statuscode);
+
+       /* Called by WaitForSingleObject and WaitForMultipleObjects, if the
+        * handle in question is "ownable" (ie mutexes), to see if the current
+        * thread already owns this handle
+        */
+       gboolean (*is_owned)(gpointer handle);
+
+       /* Called by WaitForSingleObject and WaitForMultipleObjects,
+        * if the handle in question needs a special wait function
+        * instead of using the normal handle signal mechanism.
+        * Returns the WaitForSingleObject return code.
+        */
+       guint32 (*special_wait)(gpointer handle, guint32 timeout, gboolean *alerted);
+
+       /* Called by WaitForSingleObject and WaitForMultipleObjects,
+        * if the handle in question needs some preprocessing before the
+        * signal wait.
+        */
+       void (*prewait)(gpointer handle);
+
+       /* Called when dumping the handles */
+       void (*details)(gpointer data);
+
+       /* Called to get the name of the handle type */
+       const gchar* (*typename) (void);
+
+       /* Called to get the size of the handle type */
+       gsize (*typesize) (void);
+} MonoW32HandleOps;
+
+typedef enum {
+       MONO_W32HANDLE_CAP_WAIT         = 0x01,
+       MONO_W32HANDLE_CAP_SIGNAL       = 0x02,
+       MONO_W32HANDLE_CAP_OWN          = 0x04,
+       MONO_W32HANDLE_CAP_SPECIAL_WAIT = 0x08,
+} MonoW32HandleCapability;
+
+extern guint32 mono_w32handle_fd_reserve;
+
+void
+mono_w32handle_init (void);
+
+void
+mono_w32handle_cleanup (void);
+
+void
+mono_w32handle_register_ops (MonoW32HandleType type, MonoW32HandleOps *ops);
+
+gpointer
+mono_w32handle_new (MonoW32HandleType type, gpointer handle_specific);
+
+gpointer
+mono_w32handle_new_fd (MonoW32HandleType type, int fd, gpointer handle_specific);
+
+MonoW32HandleType
+mono_w32handle_get_type (gpointer handle);
+
+gboolean
+mono_w32handle_lookup (gpointer handle, MonoW32HandleType type, gpointer *handle_specific);
+
+gpointer
+mono_w32handle_search (MonoW32HandleType type, gboolean (*check)(gpointer, gpointer), gpointer user_data, gpointer *handle_specific, gboolean search_shared);
+
+void
+mono_w32handle_foreach (gboolean (*on_each)(gpointer handle, gpointer data, gpointer user_data), gpointer user_data);
+
+void
+mono_w32handle_dump (void);
+
+void
+mono_w32handle_ref (gpointer handle);
+
+void
+mono_w32handle_unref (gpointer handle);
+
+void
+mono_w32handle_register_capabilities (MonoW32HandleType type, MonoW32HandleCapability caps);
+
+gboolean
+mono_w32handle_test_capabilities (gpointer handle, MonoW32HandleCapability caps);
+
+void
+mono_w32handle_ops_close (gpointer handle, gpointer data);
+
+void
+mono_w32handle_ops_signal (gpointer handle);
+
+gboolean
+mono_w32handle_ops_own (gpointer handle, guint32 *statuscode);
+
+gboolean
+mono_w32handle_ops_isowned (gpointer handle);
+
+guint32
+mono_w32handle_ops_specialwait (gpointer handle, guint32 timeout, gboolean *alerted);
+
+void
+mono_w32handle_ops_prewait (gpointer handle);
+
+void
+mono_w32handle_ops_details (MonoW32HandleType type, gpointer data);
+
+const gchar*
+mono_w32handle_ops_typename (MonoW32HandleType type);
+
+gsize
+mono_w32handle_ops_typesize (MonoW32HandleType type);
+
+void
+mono_w32handle_set_signal_state (gpointer handle, gboolean state, gboolean broadcast);
+
+gboolean
+mono_w32handle_issignalled (gpointer handle);
+
+int
+mono_w32handle_lock_handle (gpointer handle);
+
+int
+mono_w32handle_trylock_handle (gpointer handle);
+
+int
+mono_w32handle_unlock_handle (gpointer handle);
+
+typedef enum {
+       MONO_W32HANDLE_WAIT_RET_SUCCESS_0   =  0,
+       MONO_W32HANDLE_WAIT_RET_ABANDONED_0 =  MONO_W32HANDLE_WAIT_RET_SUCCESS_0 + MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS,
+       MONO_W32HANDLE_WAIT_RET_ALERTED     = -1,
+       MONO_W32HANDLE_WAIT_RET_TIMEOUT     = -2,
+       MONO_W32HANDLE_WAIT_RET_FAILED      = -3,
+} MonoW32HandleWaitRet;
+
+MonoW32HandleWaitRet
+mono_w32handle_wait_one (gpointer handle, guint32 timeout, gboolean alertable);
+
+MonoW32HandleWaitRet
+mono_w32handle_wait_multiple (gpointer *handles, gsize nhandles, gboolean waitall, guint32 timeout, gboolean alertable);
+
+MonoW32HandleWaitRet
+mono_w32handle_signal_and_wait (gpointer signal_handle, gpointer wait_handle, guint32 timeout, gboolean alertable);
+
+#endif /* _MONO_METADATA_W32HANDLE_H_ */
index fbf1f6177a8bcb06ce95bf8b5e94b8785144b0f3..37e8e5c462d19ef2c0d5297f7ba593adce3562d7 100644 (file)
@@ -16,7 +16,7 @@
 #include "mono/metadata/object-internals.h"
 #include "mono/utils/mono-logger-internals.h"
 #include "mono/utils/mono-threads.h"
-#include "mono/utils/w32handle.h"
+#include "mono/metadata/w32handle.h"
 
 typedef struct {
        MonoNativeThreadId tid;
diff --git a/mono/metadata/w32process-internals.h b/mono/metadata/w32process-internals.h
new file mode 100644 (file)
index 0000000..ad59f4c
--- /dev/null
@@ -0,0 +1,29 @@
+
+#ifndef _MONO_METADATA_W32PROCESS_INTERNALS_H_
+#define _MONO_METADATA_W32PROCESS_INTERNALS_H_
+
+#include <config.h>
+#include <glib.h>
+
+#include "io-layer/io-layer.h"
+
+#if !defined(HOST_WIN32)
+
+guint32
+mono_w32process_get_pid (gpointer handle);
+
+gboolean
+mono_w32process_try_get_modules (gpointer process, gpointer *modules, guint32 size, guint32 *needed);
+
+guint32
+mono_w32process_module_get_name (gpointer process, gpointer module, gunichar2 *basename, guint32 size);
+
+guint32
+mono_w32process_module_get_filename (gpointer process, gpointer module, gunichar2 *basename, guint32 size);
+
+gboolean
+mono_w32process_module_get_information (gpointer process, gpointer module, MODULEINFO *modinfo, guint32 size);
+
+#endif /* !defined(HOST_WIN32) */
+
+#endif /* _MONO_METADATA_W32PROCESS_INTERNALS_H_ */
diff --git a/mono/metadata/w32process-unix-bsd.c b/mono/metadata/w32process-unix-bsd.c
new file mode 100644 (file)
index 0000000..79655b9
--- /dev/null
@@ -0,0 +1,151 @@
+
+#include "w32process.h"
+#include "w32process-unix-internals.h"
+
+#ifdef USE_BSD_BACKEND
+
+#include <errno.h>
+#include <sys/proc.h>
+#include <sys/sysctl.h>
+#if !defined(__OpenBSD__)
+#include <sys/utsname.h>
+#endif
+#if defined(__FreeBSD__)
+#include <sys/user.h> /* struct kinfo_proc */
+#endif
+
+#include <link.h>
+
+#include "utils/mono-logger-internals.h"
+
+gchar*
+mono_w32process_get_name (pid_t pid)
+{
+       gint mib [6];
+       gsize size;
+       struct kinfo_proc *pi;
+       gchar *ret;
+
+#if defined(__FreeBSD__)
+       mib [0] = CTL_KERN;
+       mib [1] = KERN_PROC;
+       mib [2] = KERN_PROC_PID;
+       mib [3] = pid;
+       if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: sysctl() failed: %d", __func__, errno);
+               return NULL;
+       }
+
+       if ((pi = g_malloc (size)) == NULL)
+               return NULL;
+
+       if (sysctl (mib, 4, pi, &size, NULL, 0) < 0) {
+               if (errno == ENOMEM) {
+                       g_free (pi);
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Didn't allocate enough memory for kproc info", __func__);
+               }
+               return NULL;
+       }
+
+       ret = strlen (pi->ki_comm) > 0 ? g_strdup (pi->ki_comm) : NULL;
+
+       g_free (pi);
+#elif defined(__OpenBSD__)
+       mib [0] = CTL_KERN;
+       mib [1] = KERN_PROC;
+       mib [2] = KERN_PROC_PID;
+       mib [3] = pid;
+       mib [4] = sizeof(struct kinfo_proc);
+       mib [5] = 0;
+
+retry:
+       if (sysctl(mib, 6, NULL, &size, NULL, 0) < 0) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: sysctl() failed: %d", __func__, errno);
+               return NULL;
+       }
+
+       if ((pi = g_malloc (size)) == NULL)
+               return NULL;
+
+       mib[5] = (int)(size / sizeof(struct kinfo_proc));
+
+       if ((sysctl (mib, 6, pi, &size, NULL, 0) < 0) ||
+               (size != sizeof (struct kinfo_proc))) {
+               if (errno == ENOMEM) {
+                       g_free (pi);
+                       goto retry;
+               }
+               return NULL;
+       }
+
+       ret = strlen (pi->p_comm) > 0 ? g_strdup (pi->p_comm) : NULL;
+
+       g_free (pi);
+#endif
+
+       return ret;
+}
+
+gchar*
+mono_w32process_get_path (pid_t pid)
+{
+       return mono_w32process_get_name (pid);
+}
+
+static gint
+mono_w32process_get_modules_callback (struct dl_phdr_info *info, gsize size, gpointer ptr)
+{
+       if (size < offsetof (struct dl_phdr_info, dlpi_phnum) + sizeof (info->dlpi_phnum))
+               return (-1);
+
+       struct dl_phdr_info *cpy = g_calloc (1, sizeof(struct dl_phdr_info));
+       if (!cpy)
+               return (-1);
+
+       memcpy(cpy, info, sizeof(*info));
+
+       g_ptr_array_add ((GPtrArray *)ptr, cpy);
+
+       return (0);
+}
+
+GSList*
+mono_w32process_get_modules (pid_t pid)
+{
+       GSList *ret = NULL;
+       MonoW32ProcessModule *mod;
+       GPtrArray *dlarray = g_ptr_array_new();
+       gint i;
+
+       if (dl_iterate_phdr (mono_w32process_get_modules_callback, dlarray) < 0)
+               return NULL;
+
+       for (i = 0; i < dlarray->len; i++) {
+               struct dl_phdr_info *info = g_ptr_array_index (dlarray, i);
+
+               mod = g_new0 (MonoW32ProcessModule, 1);
+               mod->address_start = (gpointer)(info->dlpi_addr + info->dlpi_phdr[0].p_vaddr);
+               mod->address_end = (gpointer)(info->dlpi_addr + info->dlpi_phdr[info->dlpi_phnum - 1].p_vaddr);
+               mod->perms = g_strdup ("r--p");
+               mod->address_offset = 0;
+               mod->inode = i;
+               mod->filename = g_strdup (info->dlpi_name);
+
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: inode=%d, filename=%s, address_start=%p, address_end=%p",
+                       __func__, mod->inode, mod->filename, mod->address_start, mod->address_end);
+
+               g_free (info);
+
+               if (g_slist_find_custom (ret, mod, mono_w32process_module_equals) == NULL) {
+                       ret = g_slist_prepend (ret, mod);
+               } else {
+                       mono_w32process_module_free (mod);
+               }
+       }
+
+       g_ptr_array_free (dlarray, TRUE);
+
+       return g_slist_reverse (ret);
+}
+
+#endif
diff --git a/mono/metadata/w32process-unix-default.c b/mono/metadata/w32process-unix-default.c
new file mode 100644 (file)
index 0000000..0b48370
--- /dev/null
@@ -0,0 +1,256 @@
+
+#include "w32process.h"
+#include "w32process-unix-internals.h"
+
+#ifdef USE_DEFAULT_BACKEND
+
+#include <unistd.h>
+
+#ifdef PLATFORM_SOLARIS
+/* procfs.h cannot be included if this define is set, but it seems to work fine if it is undefined */
+#if _FILE_OFFSET_BITS == 64
+#undef _FILE_OFFSET_BITS
+#include <procfs.h>
+#define _FILE_OFFSET_BITS 64
+#else
+#include <procfs.h>
+#endif
+#endif
+
+#include "utils/mono-logger-internals.h"
+
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 242
+#endif
+
+gchar*
+mono_w32process_get_name (pid_t pid)
+{
+       FILE *fp;
+       gchar *filename;
+       gchar buf[256];
+       gchar *ret = NULL;
+
+#if defined(PLATFORM_SOLARIS)
+       filename = g_strdup_printf ("/proc/%d/psinfo", pid);
+       if ((fp = fopen (filename, "r")) != NULL) {
+               struct psinfo info;
+               int nread;
+
+               nread = fread (&info, sizeof (info), 1, fp);
+               if (nread == 1) {
+                       ret = g_strdup (info.pr_fname);
+               }
+
+               fclose (fp);
+       }
+       g_free (filename);
+#else
+       memset (buf, '\0', sizeof(buf));
+       filename = g_strdup_printf ("/proc/%d/exe", pid);
+       if (readlink (filename, buf, 255) > 0) {
+               ret = g_strdup (buf);
+       }
+       g_free (filename);
+
+       if (ret != NULL) {
+               return(ret);
+       }
+
+       filename = g_strdup_printf ("/proc/%d/cmdline", pid);
+       if ((fp = fopen (filename, "r")) != NULL) {
+               if (fgets (buf, 256, fp) != NULL) {
+                       ret = g_strdup (buf);
+               }
+
+               fclose (fp);
+       }
+       g_free (filename);
+
+       if (ret != NULL) {
+               return(ret);
+       }
+
+       filename = g_strdup_printf ("/proc/%d/stat", pid);
+       if ((fp = fopen (filename, "r")) != NULL) {
+               if (fgets (buf, 256, fp) != NULL) {
+                       char *start, *end;
+
+                       start = strchr (buf, '(');
+                       if (start != NULL) {
+                               end = strchr (start + 1, ')');
+
+                               if (end != NULL) {
+                                       ret = g_strndup (start + 1,
+                                                        end - start - 1);
+                               }
+                       }
+               }
+
+               fclose (fp);
+       }
+       g_free (filename);
+#endif
+
+       return ret;
+}
+
+gchar*
+mono_w32process_get_path (pid_t pid)
+{
+       return mono_w32process_get_name (pid);
+}
+
+static FILE *
+open_process_map (int pid, const char *mode)
+{
+       gint i;
+       const gchar *proc_path[] = {
+               "/proc/%d/maps", /* GNU/Linux */
+               "/proc/%d/map",  /* FreeBSD */
+               NULL
+       };
+
+       for (i = 0; proc_path [i]; i++) {
+               gchar *filename;
+               FILE *fp;
+
+               filename = g_strdup_printf (proc_path[i], pid);
+               fp = fopen (filename, mode);
+               g_free (filename);
+
+               if (fp)
+                       return fp;
+       }
+
+       return NULL;
+}
+
+
+GSList*
+mono_w32process_get_modules (pid_t pid)
+{
+       GSList *ret = NULL;
+       FILE *fp;
+       MonoW32ProcessModule *mod;
+       gchar buf[MAXPATHLEN + 1], *p, *endp;
+       gchar *start_start, *end_start, *prot_start, *offset_start;
+       gchar *maj_dev_start, *min_dev_start, *inode_start, prot_buf[5];
+       gpointer address_start, address_end, address_offset;
+       guint32 maj_dev, min_dev;
+       guint64 inode;
+       guint64 device;
+
+       fp = open_process_map (pid, "r");
+       if (!fp)
+               return NULL;
+
+       while (fgets (buf, sizeof(buf), fp)) {
+               p = buf;
+               while (g_ascii_isspace (*p)) ++p;
+               start_start = p;
+               if (!g_ascii_isxdigit (*start_start)) {
+                       continue;
+               }
+               address_start = (gpointer)strtoul (start_start, &endp, 16);
+               p = endp;
+               if (*p != '-') {
+                       continue;
+               }
+
+               ++p;
+               end_start = p;
+               if (!g_ascii_isxdigit (*end_start)) {
+                       continue;
+               }
+               address_end = (gpointer)strtoul (end_start, &endp, 16);
+               p = endp;
+               if (!g_ascii_isspace (*p)) {
+                       continue;
+               }
+
+               while (g_ascii_isspace (*p)) ++p;
+               prot_start = p;
+               if (*prot_start != 'r' && *prot_start != '-') {
+                       continue;
+               }
+               memcpy (prot_buf, prot_start, 4);
+               prot_buf[4] = '\0';
+               while (!g_ascii_isspace (*p)) ++p;
+
+               while (g_ascii_isspace (*p)) ++p;
+               offset_start = p;
+               if (!g_ascii_isxdigit (*offset_start)) {
+                       continue;
+               }
+               address_offset = (gpointer)strtoul (offset_start, &endp, 16);
+               p = endp;
+               if (!g_ascii_isspace (*p)) {
+                       continue;
+               }
+
+               while(g_ascii_isspace (*p)) ++p;
+               maj_dev_start = p;
+               if (!g_ascii_isxdigit (*maj_dev_start)) {
+                       continue;
+               }
+               maj_dev = strtoul (maj_dev_start, &endp, 16);
+               p = endp;
+               if (*p != ':') {
+                       continue;
+               }
+
+               ++p;
+               min_dev_start = p;
+               if (!g_ascii_isxdigit (*min_dev_start)) {
+                       continue;
+               }
+               min_dev = strtoul (min_dev_start, &endp, 16);
+               p = endp;
+               if (!g_ascii_isspace (*p)) {
+                       continue;
+               }
+
+               while (g_ascii_isspace (*p)) ++p;
+               inode_start = p;
+               if (!g_ascii_isxdigit (*inode_start)) {
+                       continue;
+               }
+               inode = (guint64)strtol (inode_start, &endp, 10);
+               p = endp;
+               if (!g_ascii_isspace (*p)) {
+                       continue;
+               }
+
+               device = makedev ((int)maj_dev, (int)min_dev);
+               if ((device == 0) && (inode == 0)) {
+                       continue;
+               }
+
+               while(g_ascii_isspace (*p)) ++p;
+               /* p now points to the filename */
+
+               mod = g_new0 (MonoW32ProcessModule, 1);
+               mod->address_start = address_start;
+               mod->address_end = address_end;
+               mod->perms = g_strdup (prot_buf);
+               mod->address_offset = address_offset;
+               mod->device = device;
+               mod->inode = inode;
+               mod->filename = g_strdup (g_strstrip (p));
+
+               if (g_slist_find_custom (ret, mod, mono_w32process_module_equals) == NULL) {
+                       ret = g_slist_prepend (ret, mod);
+               } else {
+                       mono_w32process_module_free (mod);
+               }
+       }
+
+       ret = g_slist_reverse (ret);
+
+       fclose (fp);
+
+       return(ret);
+}
+
+#endif
diff --git a/mono/metadata/w32process-unix-haiku.c b/mono/metadata/w32process-unix-haiku.c
new file mode 100644 (file)
index 0000000..4311993
--- /dev/null
@@ -0,0 +1,56 @@
+
+#include "w32process.h"
+#include "w32process-unix-internals.h"
+
+#ifdef USE_HAIKU_BACKEND
+
+#include <KernelKit.h>
+
+gchar*
+mono_w32process_get_name (pid_t pid)
+{
+       image_info imageInfo;
+       int32 cookie = 0;
+
+       if (get_next_image_info ((team_id) pid, &cookie, &imageInfo) != B_OK)
+               return NULL;
+
+       return g_strdup (imageInfo.name);
+}
+
+gchar*
+mono_w32process_get_path (pid_t pid)
+{
+       return mono_w32process_get_name (pid);
+}
+
+GSList*
+mono_w32process_get_modules (pid_t pid)
+{
+       GSList *ret = NULL;
+       MonoW32ProcessModule *mod;
+       gint32 cookie = 0;
+       image_info imageInfo;
+
+       while (get_next_image_info (B_CURRENT_TEAM, &cookie, &imageInfo) == B_OK) {
+               mod = g_new0 (MonoW32ProcessModule, 1);
+               mod->device = imageInfo.device;
+               mod->inode = imageInfo.node;
+               mod->filename = g_strdup (imageInfo.name);
+               mod->address_start = MIN (imageInfo.text, imageInfo.data);
+               mod->address_end = MAX ((uint8_t*)imageInfo.text + imageInfo.text_size,
+                       (uint8_t*)imageInfo.data + imageInfo.data_size);
+               mod->perms = g_strdup ("r--p");
+               mod->address_offset = 0;
+
+               if (g_slist_find_custom (ret, mod, mono_w32process_module_equals) == NULL) {
+                       ret = g_slist_prepend (ret, mod);
+               } else {
+                       mono_w32process_module_free (mod);
+               }
+       }
+
+       return g_slist_reverse (ret);
+}
+
+#endif
diff --git a/mono/metadata/w32process-unix-internals.h b/mono/metadata/w32process-unix-internals.h
new file mode 100644 (file)
index 0000000..71226c3
--- /dev/null
@@ -0,0 +1,57 @@
+
+#ifndef _MONO_METADATA_W32PROCESS_UNIX_INTERNALS_H_
+#define _MONO_METADATA_W32PROCESS_UNIX_INTERNALS_H_
+
+#include <config.h>
+#include <glib.h>
+
+/*
+ * FOR EXCLUSIVE USE BY w32process-unix.c
+ */
+
+#if defined(PLATFORM_MACOSX)
+#define USE_OSX_BACKEND
+#elif (defined(__OpenBSD__) || defined(__FreeBSD__)) && defined(HAVE_LINK_H)
+#define USE_BSD_BACKEND
+#elif defined(__HAIKU__)
+#define USE_HAIKU_BACKEND
+#else
+#define USE_DEFAULT_BACKEND
+#endif
+
+typedef struct {
+       gpointer address_start;
+       gpointer address_end;
+       gchar *perms;
+       gpointer address_offset;
+       guint64 device;
+       guint64 inode;
+       gchar *filename;
+} MonoW32ProcessModule;
+
+gchar*
+mono_w32process_get_name (pid_t pid);
+
+GSList*
+mono_w32process_get_modules (pid_t pid);
+
+static void
+mono_w32process_module_free (MonoW32ProcessModule *module)
+{
+       g_free (module->perms);
+       g_free (module->filename);
+       g_free (module);
+}
+
+/*
+ * Used to look through the GSList* returned by mono_w32process_get_modules
+ */
+static gint
+mono_w32process_module_equals (gconstpointer a, gconstpointer b)
+{
+       MonoW32ProcessModule *want = (MonoW32ProcessModule *)a;
+       MonoW32ProcessModule *compare = (MonoW32ProcessModule *)b;
+       return (want->device == compare->device && want->inode == compare->inode) ? 0 : 1;
+}
+
+#endif /* _MONO_METADATA_W32PROCESS_UNIX_INTERNALS_H_ */
diff --git a/mono/metadata/w32process-unix-osx.c b/mono/metadata/w32process-unix-osx.c
new file mode 100644 (file)
index 0000000..eb3d5b7
--- /dev/null
@@ -0,0 +1,160 @@
+
+#include "w32process.h"
+#include "w32process-unix-internals.h"
+
+#ifdef USE_OSX_BACKEND
+
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/proc.h>
+#include <sys/sysctl.h>
+#include <sys/utsname.h>
+#include <mach-o/dyld.h>
+#include <mach-o/getsect.h>
+
+/* sys/resource.h (for rusage) is required when using osx 10.3 (but not 10.4) */
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#include <sys/resource.h>
+#ifdef HAVE_LIBPROC_H
+/* proc_name */
+#include <libproc.h>
+#endif
+#endif
+
+#include "utils/mono-logger-internals.h"
+
+gchar*
+mono_w32process_get_name (pid_t pid)
+{
+       gchar *ret = NULL;
+
+#if defined (__mono_ppc__) || !defined (TARGET_OSX)
+       size_t size;
+       struct kinfo_proc *pi;
+       gint mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid };
+
+       if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0)
+               return(ret);
+
+       if ((pi = g_malloc (size)) == NULL)
+               return(ret);
+
+       if (sysctl (mib, 4, pi, &size, NULL, 0) < 0) {
+               if (errno == ENOMEM) {
+                       g_free (pi);
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Didn't allocate enough memory for kproc info", __func__);
+               }
+               return(ret);
+       }
+
+       if (strlen (pi->kp_proc.p_comm) > 0)
+               ret = g_strdup (pi->kp_proc.p_comm);
+
+       g_free (pi);
+#else
+       gchar buf[256];
+
+       /* No proc name on OSX < 10.5 nor ppc nor iOS */
+       memset (buf, '\0', sizeof(buf));
+       proc_name (pid, buf, sizeof(buf));
+
+       // Fixes proc_name triming values to 15 characters #32539
+       if (strlen (buf) >= MAXCOMLEN - 1) {
+               gchar path_buf [PROC_PIDPATHINFO_MAXSIZE];
+               gchar *name_buf;
+               gint path_len;
+
+               memset (path_buf, '\0', sizeof(path_buf));
+               path_len = proc_pidpath (pid, path_buf, sizeof(path_buf));
+
+               if (path_len > 0 && path_len < sizeof(path_buf)) {
+                       name_buf = path_buf + path_len;
+                       for(;name_buf > path_buf; name_buf--) {
+                               if (name_buf [0] == '/') {
+                                       name_buf++;
+                                       break;
+                               }
+                       }
+
+                       if (memcmp (buf, name_buf, MAXCOMLEN - 1) == 0)
+                               ret = g_strdup (name_buf);
+               }
+       }
+
+       if (ret == NULL && strlen (buf) > 0)
+               ret = g_strdup (buf);
+#endif
+
+       return ret;
+}
+
+gchar*
+mono_w32process_get_path (pid_t pid)
+{
+#if defined(__mono_ppc__) || !defined(TARGET_OSX)
+       return mono_w32process_get_name (pid);
+#else
+       gchar buf [PROC_PIDPATHINFO_MAXSIZE];
+       gint res;
+
+       res = proc_pidpath (pid, buf, sizeof (buf));
+       if (res <= 0)
+               return NULL;
+       if (buf [0] == '\0')
+               return NULL;
+       return g_strdup (buf);
+#endif
+}
+
+GSList*
+mono_w32process_get_modules (pid_t pid)
+{
+       GSList *ret = NULL;
+       MonoW32ProcessModule *mod;
+       guint32 count = _dyld_image_count ();
+       int i = 0;
+
+       for (i = 0; i < count; i++) {
+#if SIZEOF_VOID_P == 8
+               const struct mach_header_64 *hdr;
+               const struct section_64 *sec;
+#else
+               const struct mach_header *hdr;
+               const struct section *sec;
+#endif
+               const char *name;
+
+               name = _dyld_get_image_name (i);
+#if SIZEOF_VOID_P == 8
+               hdr = (const struct mach_header_64*)_dyld_get_image_header (i);
+               sec = getsectbynamefromheader_64 (hdr, SEG_DATA, SECT_DATA);
+#else
+               hdr = _dyld_get_image_header (i);
+               sec = getsectbynamefromheader (hdr, SEG_DATA, SECT_DATA);
+#endif
+
+               /* Some dynlibs do not have data sections on osx (#533893) */
+               if (sec == 0)
+                       continue;
+
+               mod = g_new0 (MonoW32ProcessModule, 1);
+               mod->address_start = GINT_TO_POINTER (sec->addr);
+               mod->address_end = GINT_TO_POINTER (sec->addr+sec->size);
+               mod->perms = g_strdup ("r--p");
+               mod->address_offset = 0;
+               mod->device = makedev (0, 0);
+               mod->inode = i;
+               mod->filename = g_strdup (name);
+
+               if (g_slist_find_custom (ret, mod, mono_w32process_module_equals) == NULL) {
+                       ret = g_slist_prepend (ret, mod);
+               } else {
+                       mono_w32process_module_free (mod);
+               }
+       }
+
+       return g_slist_reverse (ret);
+}
+
+#endif
diff --git a/mono/metadata/w32process-unix.c b/mono/metadata/w32process-unix.c
new file mode 100644 (file)
index 0000000..f4ae2a5
--- /dev/null
@@ -0,0 +1,2366 @@
+/*
+ * process.c: System.Diagnostics.Process support
+ *
+ * Author:
+ *     Dick Porter (dick@ximian.com)
+ *
+ * Copyright 2002 Ximian, Inc.
+ * Copyright 2002-2006 Novell, Inc.
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+
+#include <config.h>
+#include <glib.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <pthread.h>
+#include <sched.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#include <sys/time.h>
+#include <fcntl.h>
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <ctype.h>
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
+#ifdef HAVE_SYS_MKDEV_H
+#include <sys/mkdev.h>
+#endif
+
+#ifdef HAVE_UTIME_H
+#include <utime.h>
+#endif
+
+#include <mono/metadata/w32process.h>
+#include <mono/metadata/w32process-internals.h>
+#include <mono/metadata/w32process-unix-internals.h>
+#include <mono/metadata/class.h>
+#include <mono/metadata/class-internals.h>
+#include <mono/metadata/object.h>
+#include <mono/metadata/object-internals.h>
+#include <mono/metadata/metadata.h>
+#include <mono/metadata/metadata-internals.h>
+#include <mono/metadata/exception.h>
+#include <mono/io-layer/io-layer.h>
+#include <mono/metadata/w32handle.h>
+#include <mono/utils/mono-membar.h>
+#include <mono/utils/mono-logger-internals.h>
+#include <mono/utils/strenc.h>
+#include <mono/utils/mono-proclib.h>
+#include <mono/utils/mono-path.h>
+#include <mono/utils/mono-lazy-init.h>
+#include <mono/utils/mono-signal-handler.h>
+#include <mono/utils/mono-time.h>
+
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 242
+#endif
+
+#define STILL_ACTIVE ((int) 0x00000103)
+
+#define LOGDEBUG(...)
+/* define LOGDEBUG(...) g_message(__VA_ARGS__)  */
+
+/* The process' environment strings */
+#if defined(__APPLE__)
+#if defined (TARGET_OSX)
+/* Apple defines this in crt_externs.h but doesn't provide that header for 
+ * arm-apple-darwin9.  We'll manually define the symbol on Apple as it does
+ * in fact exist on all implementations (so far) 
+ */
+gchar ***_NSGetEnviron(void);
+#define environ (*_NSGetEnviron())
+#else
+static char *mono_environ[1] = { NULL };
+#define environ mono_environ
+#endif /* defined (TARGET_OSX) */
+#else
+extern char **environ;
+#endif
+
+/*
+ * Handles > _WAPI_PROCESS_UNHANDLED are pseudo handles which represent processes
+ * not started by the runtime.
+ */
+/* This marks a system process that we don't have a handle on */
+/* FIXME: Cope with PIDs > sizeof guint */
+#define _WAPI_PROCESS_UNHANDLED (1 << (8*sizeof(pid_t)-1))
+
+#define WAPI_IS_PSEUDO_PROCESS_HANDLE(handle) ((GPOINTER_TO_UINT(handle) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED)
+#define WAPI_PID_TO_HANDLE(pid) GINT_TO_POINTER (_WAPI_PROCESS_UNHANDLED + (pid))
+#define WAPI_HANDLE_TO_PID(handle) (GPOINTER_TO_UINT ((handle)) - _WAPI_PROCESS_UNHANDLED)
+
+typedef enum {
+       STARTF_USESHOWWINDOW=0x001,
+       STARTF_USESIZE=0x002,
+       STARTF_USEPOSITION=0x004,
+       STARTF_USECOUNTCHARS=0x008,
+       STARTF_USEFILLATTRIBUTE=0x010,
+       STARTF_RUNFULLSCREEN=0x020,
+       STARTF_FORCEONFEEDBACK=0x040,
+       STARTF_FORCEOFFFEEDBACK=0x080,
+       STARTF_USESTDHANDLES=0x100
+} StartupFlags;
+
+typedef struct {
+       gpointer input;
+       gpointer output;
+       gpointer error;
+} StartupHandles;
+
+typedef struct {
+#if G_BYTE_ORDER == G_BIG_ENDIAN
+       guint32 highDateTime;
+       guint32 lowDateTime;
+#else
+       guint32 lowDateTime;
+       guint32 highDateTime;
+#endif
+} ProcessTime;
+
+/*
+ * MonoProcess describes processes we create.
+ * It contains a semaphore that can be waited on in order to wait
+ * for process termination. It's accessed in our SIGCHLD handler,
+ * when status is updated (and pid cleared, to not clash with
+ * subsequent processes that may get executed).
+ */
+typedef struct _MonoProcess MonoProcess;
+struct _MonoProcess {
+       pid_t pid; /* the pid of the process. This value is only valid until the process has exited. */
+       MonoSemType exit_sem; /* this semaphore will be released when the process exits */
+       int status; /* the exit status */
+       gint32 handle_count; /* the number of handles to this mono_process instance */
+       /* we keep a ref to the creating _WapiHandle_process handle until
+        * the process has exited, so that the information there isn't lost.
+        */
+       gpointer handle;
+       gboolean freeable;
+       MonoProcess *next;
+};
+
+/* MonoW32HandleProcess is a structure containing all the required information for process handling. */
+typedef struct {
+       pid_t id;
+       guint32 exitstatus;
+       gpointer main_thread;
+       WapiFileTime create_time;
+       WapiFileTime exit_time;
+       char *proc_name;
+       size_t min_working_set;
+       size_t max_working_set;
+       gboolean exited;
+       MonoProcess *mono_process;
+} MonoW32HandleProcess;
+
+#if HAVE_SIGACTION
+static mono_lazy_init_t process_sig_chld_once = MONO_LAZY_INIT_STATUS_NOT_INITIALIZED;
+#endif
+
+static gchar *cli_launcher;
+
+/* The signal-safe logic to use mono_processes goes like this:
+ * - The list must be safe to traverse for the signal handler at all times.
+ *   It's safe to: prepend an entry (which is a single store to 'mono_processes'),
+ *   unlink an entry (assuming the unlinked entry isn't freed and doesn't
+ *   change its 'next' pointer so that it can still be traversed).
+ * When cleaning up we first unlink an entry, then we verify that
+ * the read lock isn't locked. Then we can free the entry, since
+ * we know that nobody is using the old version of the list (including
+ * the unlinked entry).
+ * We also need to lock when adding and cleaning up so that those two
+ * operations don't mess with eachother. (This lock is not used in the
+ * signal handler) */
+static MonoProcess *mono_processes;
+static mono_mutex_t mono_processes_mutex;
+static volatile gint32 mono_processes_cleaning_up;
+
+static gpointer current_process;
+
+static const gunichar2 utf16_space_bytes [2] = { 0x20, 0 };
+static const gunichar2 *utf16_space = utf16_space_bytes;
+static const gunichar2 utf16_quote_bytes [2] = { 0x22, 0 };
+static const gunichar2 *utf16_quote = utf16_quote_bytes;
+
+static void
+process_details (gpointer data)
+{
+       MonoW32HandleProcess *process_handle = (MonoW32HandleProcess *) data;
+       g_print ("id: %d, exited: %s, exitstatus: %d",
+               process_handle->id, process_handle->exited ? "true" : "false", process_handle->exitstatus);
+}
+
+static const gchar*
+process_typename (void)
+{
+       return "Process";
+}
+
+static gsize
+process_typesize (void)
+{
+       return sizeof (MonoW32HandleProcess);
+}
+
+static guint32
+process_wait (gpointer handle, guint32 timeout, gboolean *alerted)
+{
+       MonoW32HandleProcess *process_handle;
+       pid_t pid G_GNUC_UNUSED, ret;
+       int status;
+       gint64 start, now;
+       MonoProcess *mp;
+       gboolean res;
+
+       /* FIXME: We can now easily wait on processes that aren't our own children,
+        * but WaitFor*Object won't call us for pseudo handles. */
+       g_assert ((GPOINTER_TO_UINT (handle) & _WAPI_PROCESS_UNHANDLED) != _WAPI_PROCESS_UNHANDLED);
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u)", __func__, handle, timeout);
+
+       if (alerted)
+               *alerted = FALSE;
+
+       res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
+       if (!res) {
+               g_warning ("%s: error looking up process handle %p", __func__, handle);
+               return WAIT_FAILED;
+       }
+
+       if (process_handle->exited) {
+               /* We've already done this one */
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): Process already exited", __func__, handle, timeout);
+               return WAIT_OBJECT_0;
+       }
+
+       pid = process_handle->id;
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): PID: %d", __func__, handle, timeout, pid);
+
+       /* We don't need to lock mono_processes here, the entry
+        * has a handle_count > 0 which means it will not be freed. */
+       mp = process_handle->mono_process;
+       if (!mp) {
+               pid_t res;
+
+               if (pid == mono_process_current_pid ()) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): waiting on current process", __func__, handle, timeout);
+                       return WAIT_TIMEOUT;
+               }
+
+               /* This path is used when calling Process.HasExited, so
+                * it is only used to poll the state of the process, not
+                * to actually wait on it to exit */
+               g_assert (timeout == 0);
+
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): waiting on non-child process", __func__, handle, timeout);
+
+               res = waitpid (pid, &status, WNOHANG);
+               if (res == 0) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): non-child process WAIT_TIMEOUT", __func__, handle, timeout);
+                       return WAIT_TIMEOUT;
+               }
+               if (res > 0) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): non-child process waited successfully", __func__, handle, timeout);
+                       return WAIT_OBJECT_0;
+               }
+
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): non-child process WAIT_FAILED, error : %s (%d))", __func__, handle, timeout, g_strerror (errno), errno);
+               return WAIT_FAILED;
+       }
+
+       start = mono_msec_ticks ();
+       now = start;
+
+       while (1) {
+               if (timeout != INFINITE) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): waiting on semaphore for %li ms...",
+                               __func__, handle, timeout, (long)(timeout - (now - start)));
+                       ret = mono_os_sem_timedwait (&mp->exit_sem, (timeout - (now - start)), alerted ? MONO_SEM_FLAGS_ALERTABLE : MONO_SEM_FLAGS_NONE);
+               } else {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): waiting on semaphore forever...",
+                               __func__, handle, timeout);
+                       ret = mono_os_sem_wait (&mp->exit_sem, alerted ? MONO_SEM_FLAGS_ALERTABLE : MONO_SEM_FLAGS_NONE);
+               }
+
+               if (ret == MONO_SEM_TIMEDWAIT_RET_SUCCESS) {
+                       /* Success, process has exited */
+                       mono_os_sem_post (&mp->exit_sem);
+                       break;
+               }
+
+               if (ret == MONO_SEM_TIMEDWAIT_RET_TIMEDOUT) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): WAIT_TIMEOUT (timeout = 0)", __func__, handle, timeout);
+                       return WAIT_TIMEOUT;
+               }
+
+               now = mono_msec_ticks ();
+               if (now - start >= timeout) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): WAIT_TIMEOUT", __func__, handle, timeout);
+                       return WAIT_TIMEOUT;
+               }
+
+               if (alerted && ret == MONO_SEM_TIMEDWAIT_RET_ALERTED) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): WAIT_IO_COMPLETION", __func__, handle, timeout);
+                       *alerted = TRUE;
+                       return WAIT_IO_COMPLETION;
+               }
+       }
+
+       /* Process must have exited */
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): Waited successfully", __func__, handle, timeout);
+
+       status = mp ? mp->status : 0;
+       if (WIFSIGNALED (status))
+               process_handle->exitstatus = 128 + WTERMSIG (status);
+       else
+               process_handle->exitstatus = WEXITSTATUS (status);
+       _wapi_time_t_to_filetime (time (NULL), &process_handle->exit_time);
+
+       process_handle->exited = TRUE;
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): Setting pid %d signalled, exit status %d",
+                  __func__, handle, timeout, process_handle->id, process_handle->exitstatus);
+
+       mono_w32handle_set_signal_state (handle, TRUE, TRUE);
+
+       return WAIT_OBJECT_0;
+}
+
+static void
+processes_cleanup (void)
+{
+       MonoProcess *mp;
+       MonoProcess *prev = NULL;
+       GSList *finished = NULL;
+       GSList *l;
+       gpointer unref_handle;
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s", __func__);
+
+       /* Ensure we're not in here in multiple threads at once, nor recursive. */
+       if (InterlockedCompareExchange (&mono_processes_cleaning_up, 1, 0) != 0)
+               return;
+
+       for (mp = mono_processes; mp; mp = mp->next) {
+               if (mp->pid == 0 && mp->handle) {
+                       /* This process has exited and we need to remove the artifical ref
+                        * on the handle */
+                       mono_os_mutex_lock (&mono_processes_mutex);
+                       unref_handle = mp->handle;
+                       mp->handle = NULL;
+                       mono_os_mutex_unlock (&mono_processes_mutex);
+                       if (unref_handle)
+                               mono_w32handle_unref (unref_handle);
+               }
+       }
+
+       /*
+        * Remove processes which exited from the mono_processes list.
+        * We need to synchronize with the sigchld handler here, which runs
+        * asynchronously. The handler requires that the mono_processes list
+        * remain valid.
+        */
+       mono_os_mutex_lock (&mono_processes_mutex);
+
+       mp = mono_processes;
+       while (mp) {
+               if (mp->handle_count == 0 && mp->freeable) {
+                       /*
+                        * Unlink the entry.
+                        * This code can run parallel with the sigchld handler, but the
+                        * modifications it makes are safe.
+                        */
+                       if (mp == mono_processes)
+                               mono_processes = mp->next;
+                       else
+                               prev->next = mp->next;
+                       finished = g_slist_prepend (finished, mp);
+
+                       mp = mp->next;
+               } else {
+                       prev = mp;
+                       mp = mp->next;
+               }
+       }
+
+       mono_memory_barrier ();
+
+       for (l = finished; l; l = l->next) {
+               /*
+                * All the entries in the finished list are unlinked from mono_processes, and
+                * they have the 'finished' flag set, which means the sigchld handler is done
+                * accessing them.
+                */
+               mp = (MonoProcess *)l->data;
+               mono_os_sem_destroy (&mp->exit_sem);
+               g_free (mp);
+       }
+       g_slist_free (finished);
+
+       mono_os_mutex_unlock (&mono_processes_mutex);
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s done", __func__);
+
+       InterlockedDecrement (&mono_processes_cleaning_up);
+}
+
+static void
+process_close (gpointer handle, gpointer data)
+{
+       MonoW32HandleProcess *process_handle;
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s", __func__);
+
+       process_handle = (MonoW32HandleProcess *) data;
+       g_free (process_handle->proc_name);
+       process_handle->proc_name = NULL;
+       if (process_handle->mono_process)
+               InterlockedDecrement (&process_handle->mono_process->handle_count);
+       processes_cleanup ();
+}
+
+static MonoW32HandleOps process_ops = {
+       process_close,          /* close_shared */
+       NULL,                           /* signal */
+       NULL,                           /* own */
+       NULL,                           /* is_owned */
+       process_wait,                   /* special_wait */
+       NULL,                           /* prewait */
+       process_details,        /* details */
+       process_typename,       /* typename */
+       process_typesize,       /* typesize */
+};
+
+static void
+process_set_defaults (MonoW32HandleProcess *process_handle)
+{
+       /* These seem to be the defaults on w2k */
+       process_handle->min_working_set = 204800;
+       process_handle->max_working_set = 1413120;
+
+       _wapi_time_t_to_filetime (time (NULL), &process_handle->create_time);
+}
+
+static void
+process_set_name (MonoW32HandleProcess *process_handle)
+{
+       char *progname, *utf8_progname, *slash;
+
+       progname = g_get_prgname ();
+       utf8_progname = mono_utf8_from_external (progname);
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: using [%s] as prog name", __func__, progname);
+
+       if (utf8_progname) {
+               slash = strrchr (utf8_progname, '/');
+               if (slash)
+                       process_handle->proc_name = g_strdup (slash+1);
+               else
+                       process_handle->proc_name = g_strdup (utf8_progname);
+               g_free (utf8_progname);
+       }
+}
+
+void
+mono_w32process_init (void)
+{
+       MonoW32HandleProcess process_handle;
+
+       mono_w32handle_register_ops (MONO_W32HANDLE_PROCESS, &process_ops);
+
+       mono_w32handle_register_capabilities (MONO_W32HANDLE_PROCESS,
+               (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SPECIAL_WAIT));
+
+       memset (&process_handle, 0, sizeof (process_handle));
+       process_handle.id = wapi_getpid ();
+       process_set_defaults (&process_handle);
+       process_set_name (&process_handle);
+
+       current_process = mono_w32handle_new (MONO_W32HANDLE_PROCESS, &process_handle);
+       g_assert (current_process);
+
+       mono_os_mutex_init (&mono_processes_mutex);
+}
+
+void
+mono_w32process_cleanup (void)
+{
+       g_free (cli_launcher);
+}
+
+/* Check if a pid is valid - i.e. if a process exists with this pid. */
+static gboolean
+is_pid_valid (pid_t pid)
+{
+       gboolean result = FALSE;
+
+#if defined(HOST_WATCHOS)
+       result = TRUE; // TODO: Rewrite using sysctl
+#elif defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__FreeBSD__)
+       if (((kill(pid, 0) == 0) || (errno == EPERM)) && pid != 0)
+               result = TRUE;
+#elif defined(__HAIKU__)
+       team_info teamInfo;
+       if (get_team_info ((team_id)pid, &teamInfo) == B_OK)
+               result = TRUE;
+#else
+       char *dir = g_strdup_printf ("/proc/%d", pid);
+       if (!access (dir, F_OK))
+               result = TRUE;
+       g_free (dir);
+#endif
+
+       return result;
+}
+
+static int
+len16 (const gunichar2 *str)
+{
+       int len = 0;
+
+       while (*str++ != 0)
+               len++;
+
+       return len;
+}
+
+static gunichar2 *
+utf16_concat (const gunichar2 *first, ...)
+{
+       va_list args;
+       int total = 0, i;
+       const gunichar2 *s;
+       const gunichar2 *p;
+       gunichar2 *ret;
+
+       va_start (args, first);
+       total += len16 (first);
+       for (s = va_arg (args, gunichar2 *); s != NULL; s = va_arg(args, gunichar2 *))
+               total += len16 (s);
+       va_end (args);
+
+       ret = g_new (gunichar2, total + 1);
+       if (ret == NULL)
+               return NULL;
+
+       ret [total] = 0;
+       i = 0;
+       for (s = first; *s != 0; s++)
+               ret [i++] = *s;
+       va_start (args, first);
+       for (s = va_arg (args, gunichar2 *); s != NULL; s = va_arg (args, gunichar2 *)){
+               for (p = s; *p != 0; p++)
+                       ret [i++] = *p;
+       }
+       va_end (args);
+
+       return ret;
+}
+
+guint32
+mono_w32process_get_pid (gpointer handle)
+{
+       MonoW32HandleProcess *process_handle;
+       gboolean res;
+
+       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (handle)) {
+               /* This is a pseudo handle */
+               return WAPI_HANDLE_TO_PID (handle);
+       }
+
+       res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
+       if (!res) {
+               SetLastError (ERROR_INVALID_HANDLE);
+               return 0;
+       }
+
+       return process_handle->id;
+}
+
+static gboolean
+process_open_compare (gpointer handle, gpointer user_data)
+{
+       gboolean res;
+       MonoW32HandleProcess *process_handle;
+       pid_t wanted_pid, checking_pid;
+
+       g_assert (!WAPI_IS_PSEUDO_PROCESS_HANDLE (handle));
+
+       res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
+       if (!res)
+               g_error ("%s: unknown process handle %p", __func__, handle);
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: looking at process %d", __func__, process_handle->id);
+
+       checking_pid = process_handle->id;
+       if (checking_pid == 0)
+               return FALSE;
+
+       wanted_pid = GPOINTER_TO_UINT (user_data);
+
+       /* It's possible to have more than one process handle with the
+        * same pid, but only the one running process can be
+        * unsignalled.
+        * If the handle is blown away in the window between
+        * returning TRUE here and mono_w32handle_search pinging
+        * the timestamp, the search will continue. */
+       return checking_pid == wanted_pid && !mono_w32handle_issignalled (handle);
+}
+
+HANDLE
+ves_icall_System_Diagnostics_Process_GetProcess_internal (guint32 pid)
+{
+       gpointer handle;
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: looking for process %d", __func__, pid);
+
+       handle = mono_w32handle_search (MONO_W32HANDLE_PROCESS, process_open_compare, GUINT_TO_POINTER (pid), NULL, TRUE);
+       if (handle) {
+               /* mono_w32handle_search () already added a ref */
+               return handle;
+       }
+
+       if (is_pid_valid (pid)) {
+               /* Return a pseudo handle for processes we don't have handles for */
+               return WAPI_PID_TO_HANDLE (pid);
+       } else {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find pid %d", __func__, pid);
+
+               SetLastError (ERROR_PROC_NOT_FOUND);
+               return NULL;
+       }
+}
+
+static gboolean
+match_procname_to_modulename (char *procname, char *modulename)
+{
+       char* lastsep = NULL;
+       char* lastsep2 = NULL;
+       char* pname = NULL;
+       char* mname = NULL;
+       gboolean result = FALSE;
+
+       if (procname == NULL || modulename == NULL)
+               return (FALSE);
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: procname=\"%s\", modulename=\"%s\"", __func__, procname, modulename);
+       pname = mono_path_resolve_symlinks (procname);
+       mname = mono_path_resolve_symlinks (modulename);
+
+       if (!strcmp (pname, mname))
+               result = TRUE;
+
+       if (!result) {
+               lastsep = strrchr (mname, '/');
+               if (lastsep)
+                       if (!strcmp (lastsep+1, pname))
+                               result = TRUE;
+               if (!result) {
+                       lastsep2 = strrchr (pname, '/');
+                       if (lastsep2){
+                               if (lastsep) {
+                                       if (!strcmp (lastsep+1, lastsep2+1))
+                                               result = TRUE;
+                               } else {
+                                       if (!strcmp (mname, lastsep2+1))
+                                               result = TRUE;
+                               }
+                       }
+               }
+       }
+
+       g_free (pname);
+       g_free (mname);
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: result is %d", __func__, result);
+       return result;
+}
+
+gboolean
+mono_w32process_try_get_modules (gpointer process, gpointer *modules, guint32 size, guint32 *needed)
+{
+       MonoW32HandleProcess *process_handle;
+       GSList *mods = NULL;
+       MonoW32ProcessModule *module;
+       guint32 count, avail = size / sizeof(gpointer);
+       int i;
+       pid_t pid;
+       char *proc_name = NULL;
+       gboolean res;
+
+       /* Store modules in an array of pointers (main module as
+        * modules[0]), using the load address for each module as a
+        * token.  (Use 'NULL' as an alternative for the main module
+        * so that the simple implementation can just return one item
+        * for now.)  Get the info from /proc/<pid>/maps on linux,
+        * /proc/<pid>/map on FreeBSD, other systems will have to
+        * implement /dev/kmem reading or whatever other horrid
+        * technique is needed.
+        */
+       if (size < sizeof(gpointer))
+               return FALSE;
+
+       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) {
+               pid = WAPI_HANDLE_TO_PID (process);
+               proc_name = mono_w32process_get_name (pid);
+       } else {
+               res = mono_w32handle_lookup (process, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
+               if (!res) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, process);
+                       return FALSE;
+               }
+
+               pid = process_handle->id;
+               proc_name = g_strdup (process_handle->proc_name);
+       }
+
+       if (!proc_name) {
+               modules[0] = NULL;
+               *needed = sizeof(gpointer);
+               return TRUE;
+       }
+
+       mods = mono_w32process_get_modules (pid);
+       if (!mods) {
+               modules[0] = NULL;
+               *needed = sizeof(gpointer);
+               g_free (proc_name);
+               return TRUE;
+       }
+
+       count = g_slist_length (mods);
+
+       /* count + 1 to leave slot 0 for the main module */
+       *needed = sizeof(gpointer) * (count + 1);
+
+       /*
+        * Use the NULL shortcut, as the first line in
+        * /proc/<pid>/maps isn't the executable, and we need
+        * that first in the returned list. Check the module name
+        * to see if it ends with the proc name and substitute
+        * the first entry with it.  FIXME if this turns out to
+        * be a problem.
+        */
+       modules[0] = NULL;
+       for (i = 0; i < (avail - 1) && i < count; i++) {
+               module = (MonoW32ProcessModule *)g_slist_nth_data (mods, i);
+               if (modules[0] != NULL)
+                       modules[i] = module->address_start;
+               else if (match_procname_to_modulename (proc_name, module->filename))
+                       modules[0] = module->address_start;
+               else
+                       modules[i + 1] = module->address_start;
+       }
+
+       for (i = 0; i < count; i++) {
+               mono_w32process_module_free ((MonoW32ProcessModule *)g_slist_nth_data (mods, i));
+       }
+       g_slist_free (mods);
+       g_free (proc_name);
+
+       return TRUE;
+}
+
+guint32
+mono_w32process_module_get_filename (gpointer process, gpointer module, gunichar2 *basename, guint32 size)
+{
+       gint pid, len;
+       gsize bytes;
+       gchar *path;
+       gunichar2 *proc_path;
+
+       size *= sizeof (gunichar2); /* adjust for unicode characters */
+
+       if (basename == NULL || size == 0)
+               return 0;
+
+       pid = mono_w32process_get_pid (process);
+
+       path = mono_w32process_get_path (pid);
+       if (path == NULL)
+               return 0;
+
+       proc_path = mono_unicode_from_external (path, &bytes);
+       g_free (path);
+
+       if (proc_path == NULL)
+               return 0;
+
+       len = (bytes / 2);
+
+       /* Add the terminator */
+       bytes += 2;
+
+       if (size < bytes) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Size %d smaller than needed (%ld); truncating", __func__, size, bytes);
+               memcpy (basename, proc_path, size);
+       } else {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Size %d larger than needed (%ld)", __func__, size, bytes);
+               memcpy (basename, proc_path, bytes);
+       }
+
+       g_free (proc_path);
+
+       return len;
+}
+
+guint32
+mono_w32process_module_get_name (gpointer process, gpointer module, gunichar2 *basename, guint32 size)
+{
+       MonoW32HandleProcess *process_handle;
+       pid_t pid;
+       gunichar2 *procname;
+       char *procname_ext = NULL;
+       glong len;
+       gsize bytes;
+       GSList *mods = NULL;
+       MonoW32ProcessModule *found_module;
+       guint32 count;
+       int i;
+       char *proc_name = NULL;
+       gboolean res;
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Getting module base name, process handle %p module %p",
+                  __func__, process, module);
+
+       size = size * sizeof (gunichar2); /* adjust for unicode characters */
+
+       if (basename == NULL || size == 0)
+               return 0;
+
+       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) {
+               /* This is a pseudo handle */
+               pid = (pid_t)WAPI_HANDLE_TO_PID (process);
+               proc_name = mono_w32process_get_name (pid);
+       } else {
+               res = mono_w32handle_lookup (process, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
+               if (!res) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, process);
+                       return 0;
+               }
+
+               pid = process_handle->id;
+               proc_name = g_strdup (process_handle->proc_name);
+       }
+
+       mods = mono_w32process_get_modules (pid);
+       if (!mods) {
+               g_free (proc_name);
+               return 0;
+       }
+
+       count = g_slist_length (mods);
+
+       /* If module != NULL compare the address.
+        * If module == NULL we are looking for the main module.
+        * The best we can do for now check it the module name end with the process name.
+        */
+       for (i = 0; i < count; i++) {
+               found_module = (MonoW32ProcessModule *)g_slist_nth_data (mods, i);
+               if (procname_ext == NULL &&
+                       ((module == NULL && match_procname_to_modulename (proc_name, found_module->filename)) ||
+                        (module != NULL && found_module->address_start == module))) {
+                       procname_ext = g_path_get_basename (found_module->filename);
+               }
+
+               mono_w32process_module_free (found_module);
+       }
+
+       if (procname_ext == NULL) {
+               /* If it's *still* null, we might have hit the
+                * case where reading /proc/$pid/maps gives an
+                * empty file for this user.
+                */
+               procname_ext = mono_w32process_get_name (pid);
+       }
+
+       g_slist_free (mods);
+       g_free (proc_name);
+
+       if (procname_ext) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Process name is [%s]", __func__,
+                          procname_ext);
+
+               procname = mono_unicode_from_external (procname_ext, &bytes);
+               if (procname == NULL) {
+                       /* bugger */
+                       g_free (procname_ext);
+                       return 0;
+               }
+
+               len = (bytes / 2);
+
+               /* Add the terminator */
+               bytes += 2;
+
+               if (size < bytes) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Size %d smaller than needed (%ld); truncating", __func__, size, bytes);
+
+                       memcpy (basename, procname, size);
+               } else {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Size %d larger than needed (%ld)",
+                                  __func__, size, bytes);
+
+                       memcpy (basename, procname, bytes);
+               }
+
+               g_free (procname);
+               g_free (procname_ext);
+
+               return len;
+       }
+
+       return 0;
+}
+
+gboolean
+mono_w32process_module_get_information (gpointer process, gpointer module, WapiModuleInfo *modinfo, guint32 size)
+{
+       MonoW32HandleProcess *process_handle;
+       pid_t pid;
+       GSList *mods = NULL;
+       MonoW32ProcessModule *found_module;
+       guint32 count;
+       int i;
+       gboolean ret = FALSE;
+       char *proc_name = NULL;
+       gboolean res;
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Getting module info, process handle %p module %p",
+                  __func__, process, module);
+
+       if (modinfo == NULL || size < sizeof (WapiModuleInfo))
+               return FALSE;
+
+       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) {
+               pid = (pid_t)WAPI_HANDLE_TO_PID (process);
+               proc_name = mono_w32process_get_name (pid);
+       } else {
+               res = mono_w32handle_lookup (process, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
+               if (!res) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, process);
+                       return FALSE;
+               }
+
+               pid = process_handle->id;
+               proc_name = g_strdup (process_handle->proc_name);
+       }
+
+       mods = mono_w32process_get_modules (pid);
+       if (!mods) {
+               g_free (proc_name);
+               return FALSE;
+       }
+
+       count = g_slist_length (mods);
+
+       /* If module != NULL compare the address.
+        * If module == NULL we are looking for the main module.
+        * The best we can do for now check it the module name end with the process name.
+        */
+       for (i = 0; i < count; i++) {
+                       found_module = (MonoW32ProcessModule *)g_slist_nth_data (mods, i);
+                       if (ret == FALSE &&
+                               ((module == NULL && match_procname_to_modulename (proc_name, found_module->filename)) ||
+                                (module != NULL && found_module->address_start == module))) {
+                               modinfo->lpBaseOfDll = found_module->address_start;
+                               modinfo->SizeOfImage = (gsize)(found_module->address_end) - (gsize)(found_module->address_start);
+                               modinfo->EntryPoint = found_module->address_offset;
+                               ret = TRUE;
+                       }
+
+                       mono_w32process_module_free (found_module);
+       }
+
+       g_slist_free (mods);
+       g_free (proc_name);
+
+       return ret;
+}
+
+static void
+switch_dir_separators (char *path)
+{
+       size_t i, pathLength = strlen(path);
+       
+       /* Turn all the slashes round the right way, except for \' */
+       /* There are probably other characters that need to be excluded as well. */
+       for (i = 0; i < pathLength; i++) {
+               if (path[i] == '\\' && i < pathLength - 1 && path[i+1] != '\'' )
+                       path[i] = '/';
+       }
+}
+
+#if HAVE_SIGACTION
+
+MONO_SIGNAL_HANDLER_FUNC (static, mono_sigchld_signal_handler, (int _dummy, siginfo_t *info, void *context))
+{
+       int status;
+       int pid;
+       MonoProcess *p;
+
+       do {
+               do {
+                       pid = waitpid (-1, &status, WNOHANG);
+               } while (pid == -1 && errno == EINTR);
+
+               if (pid <= 0)
+                       break;
+
+               /*
+                * This can run concurrently with the code in the rest of this module.
+                */
+               for (p = mono_processes; p; p = p->next) {
+                       if (p->pid == pid) {
+                               break;
+                       }
+               }
+               if (p) {
+                       p->pid = 0; /* this pid doesn't exist anymore, clear it */
+                       p->status = status;
+                       mono_os_sem_post (&p->exit_sem);
+                       mono_memory_barrier ();
+                       /* Mark this as freeable, the pointer becomes invalid afterwards */
+                       p->freeable = TRUE;
+               }
+       } while (1);
+}
+
+static void
+process_add_sigchld_handler (void)
+{
+       struct sigaction sa;
+
+       sa.sa_sigaction = mono_sigchld_signal_handler;
+       sigemptyset (&sa.sa_mask);
+       sa.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
+       g_assert (sigaction (SIGCHLD, &sa, NULL) != -1);
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "Added SIGCHLD handler");
+}
+
+#endif
+
+static gboolean
+is_readable_or_executable (const char *prog)
+{
+       struct stat buf;
+       int a = access (prog, R_OK);
+       int b = access (prog, X_OK);
+       if (a != 0 && b != 0)
+               return FALSE;
+       if (stat (prog, &buf))
+               return FALSE;
+       if (S_ISREG (buf.st_mode))
+               return TRUE;
+       return FALSE;
+}
+
+static gboolean
+is_executable (const char *prog)
+{
+       struct stat buf;
+       if (access (prog, X_OK) != 0)
+               return FALSE;
+       if (stat (prog, &buf))
+               return FALSE;
+       if (S_ISREG (buf.st_mode))
+               return TRUE;
+       return FALSE;
+}
+
+static gboolean
+is_managed_binary (const char *filename)
+{
+       int original_errno = errno;
+#if defined(HAVE_LARGE_FILE_SUPPORT) && defined(O_LARGEFILE)
+       int file = open (filename, O_RDONLY | O_LARGEFILE);
+#else
+       int file = open (filename, O_RDONLY);
+#endif
+       off_t new_offset;
+       unsigned char buffer[8];
+       off_t file_size, optional_header_offset;
+       off_t pe_header_offset, clr_header_offset;
+       gboolean managed = FALSE;
+       int num_read;
+       guint32 first_word, second_word, magic_number;
+       
+       /* If we are unable to open the file, then we definitely
+        * can't say that it is managed. The child mono process
+        * probably wouldn't be able to open it anyway.
+        */
+       if (file < 0) {
+               errno = original_errno;
+               return FALSE;
+       }
+
+       /* Retrieve the length of the file for future sanity checks. */
+       file_size = lseek (file, 0, SEEK_END);
+       lseek (file, 0, SEEK_SET);
+
+       /* We know we need to read a header field at offset 60. */
+       if (file_size < 64)
+               goto leave;
+
+       num_read = read (file, buffer, 2);
+
+       if ((num_read != 2) || (buffer[0] != 'M') || (buffer[1] != 'Z'))
+               goto leave;
+
+       new_offset = lseek (file, 60, SEEK_SET);
+
+       if (new_offset != 60)
+               goto leave;
+       
+       num_read = read (file, buffer, 4);
+
+       if (num_read != 4)
+               goto leave;
+       pe_header_offset =  buffer[0]
+               | (buffer[1] <<  8)
+               | (buffer[2] << 16)
+               | (buffer[3] << 24);
+       
+       if (pe_header_offset + 24 > file_size)
+               goto leave;
+
+       new_offset = lseek (file, pe_header_offset, SEEK_SET);
+
+       if (new_offset != pe_header_offset)
+               goto leave;
+
+       num_read = read (file, buffer, 4);
+
+       if ((num_read != 4) || (buffer[0] != 'P') || (buffer[1] != 'E') || (buffer[2] != 0) || (buffer[3] != 0))
+               goto leave;
+
+       /*
+        * Verify that the header we want in the optional header data
+        * is present in this binary.
+        */
+       new_offset = lseek (file, pe_header_offset + 20, SEEK_SET);
+
+       if (new_offset != pe_header_offset + 20)
+               goto leave;
+
+       num_read = read (file, buffer, 2);
+
+       if ((num_read != 2) || ((buffer[0] | (buffer[1] << 8)) < 216))
+               goto leave;
+
+       optional_header_offset = pe_header_offset + 24;
+
+       /* Read the PE magic number */
+       new_offset = lseek (file, optional_header_offset, SEEK_SET);
+       
+       if (new_offset != optional_header_offset)
+               goto leave;
+
+       num_read = read (file, buffer, 2);
+
+       if (num_read != 2)
+               goto leave;
+
+       magic_number = (buffer[0] | (buffer[1] << 8));
+       
+       if (magic_number == 0x10B)  // PE32
+               clr_header_offset = 208;
+       else if (magic_number == 0x20B)  // PE32+
+               clr_header_offset = 224;
+       else
+               goto leave;
+
+       /* Read the CLR header address and size fields. These will be
+        * zero if the binary is not managed.
+        */
+       new_offset = lseek (file, optional_header_offset + clr_header_offset, SEEK_SET);
+
+       if (new_offset != optional_header_offset + clr_header_offset)
+               goto leave;
+
+       num_read = read (file, buffer, 8);
+       
+       /* We are not concerned with endianness, only with
+        * whether it is zero or not.
+        */
+       first_word = *(guint32 *)&buffer[0];
+       second_word = *(guint32 *)&buffer[4];
+       
+       if ((num_read != 8) || (first_word == 0) || (second_word == 0))
+               goto leave;
+       
+       managed = TRUE;
+
+leave:
+       close (file);
+       errno = original_errno;
+       return managed;
+}
+
+static gboolean
+process_create (const gunichar2 *appname, const gunichar2 *cmdline, gpointer new_environ,
+       const gunichar2 *cwd, StartupHandles *startup_handles, MonoW32ProcessInfo *process_info)
+{
+#if defined (HAVE_FORK) && defined (HAVE_EXECVE)
+       char *cmd = NULL, *prog = NULL, *full_prog = NULL, *args = NULL, *args_after_prog = NULL;
+       char *dir = NULL, **env_strings = NULL, **argv = NULL;
+       guint32 i, env_count = 0;
+       gboolean ret = FALSE;
+       gpointer handle = NULL;
+       MonoW32HandleProcess process_handle = {0}, *process_handle_data;
+       GError *gerr = NULL;
+       int in_fd, out_fd, err_fd;
+       pid_t pid = 0;
+       int startup_pipe [2] = {-1, -1};
+       int dummy;
+       MonoProcess *mono_process;
+       gboolean fork_failed = FALSE;
+       gboolean res;
+
+#if HAVE_SIGACTION
+       mono_lazy_initialize (&process_sig_chld_once, process_add_sigchld_handler);
+#endif
+
+       /* appname and cmdline specify the executable and its args:
+        *
+        * If appname is not NULL, it is the name of the executable.
+        * Otherwise the executable is the first token in cmdline.
+        *
+        * Executable searching:
+        *
+        * If appname is not NULL, it can specify the full path and
+        * file name, or else a partial name and the current directory
+        * will be used.  There is no additional searching.
+        *
+        * If appname is NULL, the first whitespace-delimited token in
+        * cmdline is used.  If the name does not contain a full
+        * directory path, the search sequence is:
+        *
+        * 1) The directory containing the current process
+        * 2) The current working directory
+        * 3) The windows system directory  (Ignored)
+        * 4) The windows directory (Ignored)
+        * 5) $PATH
+        *
+        * Just to make things more interesting, tokens can contain
+        * white space if they are surrounded by quotation marks.  I'm
+        * beginning to understand just why windows apps are generally
+        * so crap, with an API like this :-(
+        */
+       if (appname != NULL) {
+               cmd = mono_unicode_to_external (appname);
+               if (cmd == NULL) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unicode conversion returned NULL",
+                                  __func__);
+
+                       SetLastError (ERROR_PATH_NOT_FOUND);
+                       goto free_strings;
+               }
+
+               switch_dir_separators(cmd);
+       }
+
+       if (cmdline != NULL) {
+               args = mono_unicode_to_external (cmdline);
+               if (args == NULL) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unicode conversion returned NULL", __func__);
+
+                       SetLastError (ERROR_PATH_NOT_FOUND);
+                       goto free_strings;
+               }
+       }
+
+       if (cwd != NULL) {
+               dir = mono_unicode_to_external (cwd);
+               if (dir == NULL) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unicode conversion returned NULL", __func__);
+
+                       SetLastError (ERROR_PATH_NOT_FOUND);
+                       goto free_strings;
+               }
+
+               /* Turn all the slashes round the right way */
+               switch_dir_separators(dir);
+       }
+
+
+       /* We can't put off locating the executable any longer :-( */
+       if (cmd != NULL) {
+               char *unquoted;
+               if (g_ascii_isalpha (cmd[0]) && (cmd[1] == ':')) {
+                       /* Strip off the drive letter.  I can't
+                        * believe that CP/M holdover is still
+                        * visible...
+                        */
+                       g_memmove (cmd, cmd+2, strlen (cmd)-2);
+                       cmd[strlen (cmd)-2] = '\0';
+               }
+
+               unquoted = g_shell_unquote (cmd, NULL);
+               if (unquoted[0] == '/') {
+                       /* Assume full path given */
+                       prog = g_strdup (unquoted);
+
+                       /* Executable existing ? */
+                       if (!is_readable_or_executable (prog)) {
+                               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Couldn't find executable %s",
+                                          __func__, prog);
+                               g_free (unquoted);
+                               SetLastError (ERROR_FILE_NOT_FOUND);
+                               goto free_strings;
+                       }
+               } else {
+                       /* Search for file named by cmd in the current
+                        * directory
+                        */
+                       char *curdir = g_get_current_dir ();
+
+                       prog = g_strdup_printf ("%s/%s", curdir, unquoted);
+                       g_free (curdir);
+
+                       /* And make sure it's readable */
+                       if (!is_readable_or_executable (prog)) {
+                               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Couldn't find executable %s",
+                                          __func__, prog);
+                               g_free (unquoted);
+                               SetLastError (ERROR_FILE_NOT_FOUND);
+                               goto free_strings;
+                       }
+               }
+               g_free (unquoted);
+
+               args_after_prog = args;
+       } else {
+               char *token = NULL;
+               char quote;
+
+               /* Dig out the first token from args, taking quotation
+                * marks into account
+                */
+
+               /* First, strip off all leading whitespace */
+               args = g_strchug (args);
+
+               /* args_after_prog points to the contents of args
+                * after token has been set (otherwise argv[0] is
+                * duplicated)
+                */
+               args_after_prog = args;
+
+               /* Assume the opening quote will always be the first
+                * character
+                */
+               if (args[0] == '\"' || args [0] == '\'') {
+                       quote = args [0];
+                       for (i = 1; args[i] != '\0' && args[i] != quote; i++);
+                       if (args [i + 1] == '\0' || g_ascii_isspace (args[i+1])) {
+                               /* We found the first token */
+                               token = g_strndup (args+1, i-1);
+                               args_after_prog = g_strchug (args + i + 1);
+                       } else {
+                               /* Quotation mark appeared in the
+                                * middle of the token.  Just give the
+                                * whole first token, quotes and all,
+                                * to exec.
+                                */
+                       }
+               }
+
+               if (token == NULL) {
+                       /* No quote mark, or malformed */
+                       for (i = 0; args[i] != '\0'; i++) {
+                               if (g_ascii_isspace (args[i])) {
+                                       token = g_strndup (args, i);
+                                       args_after_prog = args + i + 1;
+                                       break;
+                               }
+                       }
+               }
+
+               if (token == NULL && args[0] != '\0') {
+                       /* Must be just one token in the string */
+                       token = g_strdup (args);
+                       args_after_prog = NULL;
+               }
+
+               if (token == NULL) {
+                       /* Give up */
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Couldn't find what to exec", __func__);
+
+                       SetLastError (ERROR_PATH_NOT_FOUND);
+                       goto free_strings;
+               }
+
+               /* Turn all the slashes round the right way. Only for
+                * the prg. name
+                */
+               switch_dir_separators(token);
+
+               if (g_ascii_isalpha (token[0]) && (token[1] == ':')) {
+                       /* Strip off the drive letter.  I can't
+                        * believe that CP/M holdover is still
+                        * visible...
+                        */
+                       g_memmove (token, token+2, strlen (token)-2);
+                       token[strlen (token)-2] = '\0';
+               }
+
+               if (token[0] == '/') {
+                       /* Assume full path given */
+                       prog = g_strdup (token);
+
+                       /* Executable existing ? */
+                       if (!is_readable_or_executable (prog)) {
+                               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Couldn't find executable %s",
+                                          __func__, token);
+                               g_free (token);
+                               SetLastError (ERROR_FILE_NOT_FOUND);
+                               goto free_strings;
+                       }
+               } else {
+                       char *curdir = g_get_current_dir ();
+
+                       /* FIXME: Need to record the directory
+                        * containing the current process, and check
+                        * that for the new executable as the first
+                        * place to look
+                        */
+
+                       prog = g_strdup_printf ("%s/%s", curdir, token);
+                       g_free (curdir);
+
+                       /* I assume X_OK is the criterion to use,
+                        * rather than F_OK
+                        *
+                        * X_OK is too strict *if* the target is a CLR binary
+                        */
+                       if (!is_readable_or_executable (prog)) {
+                               g_free (prog);
+                               prog = g_find_program_in_path (token);
+                               if (prog == NULL) {
+                                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Couldn't find executable %s", __func__, token);
+
+                                       g_free (token);
+                                       SetLastError (ERROR_FILE_NOT_FOUND);
+                                       goto free_strings;
+                               }
+                       }
+               }
+
+               g_free (token);
+       }
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Exec prog [%s] args [%s]",
+               __func__, prog, args_after_prog);
+
+       /* Check for CLR binaries; if found, we will try to invoke
+        * them using the same mono binary that started us.
+        */
+       if (is_managed_binary (prog)) {
+               gunichar2 *newapp, *newcmd;
+               gsize bytes_ignored;
+
+               newapp = mono_unicode_from_external (cli_launcher ? cli_launcher : "mono", &bytes_ignored);
+               if (newapp) {
+                       if (appname)
+                               newcmd = utf16_concat (utf16_quote, newapp, utf16_quote, utf16_space, appname, utf16_space, cmdline, NULL);
+                       else
+                               newcmd = utf16_concat (utf16_quote, newapp, utf16_quote, utf16_space, cmdline, NULL);
+
+                       g_free (newapp);
+
+                       if (newcmd) {
+                               ret = process_create (NULL, newcmd, new_environ, cwd, startup_handles, process_info);
+
+                               g_free (newcmd);
+
+                               goto free_strings;
+                       }
+               }
+       } else {
+               if (!is_executable (prog)) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Executable permisson not set on %s", __func__, prog);
+                       SetLastError (ERROR_ACCESS_DENIED);
+                       goto free_strings;
+               }
+       }
+
+       if (args_after_prog != NULL && *args_after_prog) {
+               char *qprog;
+
+               qprog = g_shell_quote (prog);
+               full_prog = g_strconcat (qprog, " ", args_after_prog, NULL);
+               g_free (qprog);
+       } else {
+               full_prog = g_shell_quote (prog);
+       }
+
+       ret = g_shell_parse_argv (full_prog, NULL, &argv, &gerr);
+       if (ret == FALSE) {
+               g_message ("process_create: %s\n", gerr->message);
+               g_error_free (gerr);
+               gerr = NULL;
+               goto free_strings;
+       }
+
+       if (startup_handles) {
+               in_fd = GPOINTER_TO_UINT (startup_handles->input);
+               out_fd = GPOINTER_TO_UINT (startup_handles->output);
+               err_fd = GPOINTER_TO_UINT (startup_handles->error);
+       } else {
+               in_fd = GPOINTER_TO_UINT (GetStdHandle (STD_INPUT_HANDLE));
+               out_fd = GPOINTER_TO_UINT (GetStdHandle (STD_OUTPUT_HANDLE));
+               err_fd = GPOINTER_TO_UINT (GetStdHandle (STD_ERROR_HANDLE));
+       }
+
+       process_handle.proc_name = g_strdup (prog);
+
+       process_set_defaults (&process_handle);
+
+       handle = mono_w32handle_new (MONO_W32HANDLE_PROCESS, &process_handle);
+       if (handle == INVALID_HANDLE_VALUE) {
+               g_warning ("%s: error creating process handle", __func__);
+
+               ret = FALSE;
+               SetLastError (ERROR_OUTOFMEMORY);
+               goto free_strings;
+       }
+
+       /* new_environ is a block of NULL-terminated strings, which
+        * is itself NULL-terminated. Of course, passing an array of
+        * string pointers would have made things too easy :-(
+        *
+        * If new_environ is not NULL it specifies the entire set of
+        * environment variables in the new process.  Otherwise the
+        * new process inherits the same environment.
+        */
+       if (new_environ) {
+               gunichar2 *new_environp;
+
+               /* Count the number of strings */
+               for (new_environp = (gunichar2 *)new_environ; *new_environp; new_environp++) {
+                       env_count++;
+                       while (*new_environp)
+                               new_environp++;
+               }
+
+               /* +2: one for the process handle value, and the last
+                * one is NULL
+                */
+               env_strings = g_new0 (char *, env_count + 2);
+
+               /* Copy each environ string into 'strings' turning it
+                * into utf8 (or the requested encoding) at the same
+                * time
+                */
+               env_count = 0;
+               for (new_environp = (gunichar2 *)new_environ; *new_environp; new_environp++) {
+                       env_strings[env_count] = mono_unicode_to_external (new_environp);
+                       env_count++;
+                       while (*new_environp) {
+                               new_environp++;
+                       }
+               }
+       } else {
+               for (i = 0; environ[i] != NULL; i++)
+                       env_count++;
+
+               /* +2: one for the process handle value, and the last
+                * one is NULL
+                */
+               env_strings = g_new0 (char *, env_count + 2);
+
+               /* Copy each environ string into 'strings' turning it
+                * into utf8 (or the requested encoding) at the same
+                * time
+                */
+               env_count = 0;
+               for (i = 0; environ[i] != NULL; i++) {
+                       env_strings[env_count] = g_strdup (environ[i]);
+                       env_count++;
+               }
+       }
+
+       /* Create a pipe to make sure the child doesn't exit before
+        * we can add the process to the linked list of mono_processes */
+       if (pipe (startup_pipe) == -1) {
+               /* Could not create the pipe to synchroniz process startup. We'll just not synchronize.
+                * This is just for a very hard to hit race condition in the first place */
+               startup_pipe [0] = startup_pipe [1] = -1;
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: new process startup not synchronized. We may not notice if the newly created process exits immediately.", __func__);
+       }
+
+       switch (pid = fork ()) {
+       case -1: /* Error */ {
+               SetLastError (ERROR_OUTOFMEMORY);
+               ret = FALSE;
+               fork_failed = TRUE;
+               break;
+       }
+       case 0: /* Child */ {
+               if (startup_pipe [0] != -1) {
+                       /* Wait until the parent has updated it's internal data */
+                       ssize_t _i G_GNUC_UNUSED = read (startup_pipe [0], &dummy, 1);
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: child: parent has completed its setup", __func__);
+                       close (startup_pipe [0]);
+                       close (startup_pipe [1]);
+               }
+
+               /* should we detach from the process group? */
+
+               /* Connect stdin, stdout and stderr */
+               dup2 (in_fd, 0);
+               dup2 (out_fd, 1);
+               dup2 (err_fd, 2);
+
+               /* Close all file descriptors */
+               for (i = mono_w32handle_fd_reserve - 1; i > 2; i--)
+                       close (i);
+
+#ifdef DEBUG_ENABLED
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: exec()ing [%s] in dir [%s]", __func__, cmd,
+                          dir == NULL?".":dir);
+               for (i = 0; argv[i] != NULL; i++)
+                       g_message ("arg %d: [%s]", i, argv[i]);
+
+               for (i = 0; env_strings[i] != NULL; i++)
+                       g_message ("env %d: [%s]", i, env_strings[i]);
+#endif
+
+               /* set cwd */
+               if (dir != NULL && chdir (dir) == -1) {
+                       /* set error */
+                       _exit (-1);
+               }
+
+               /* exec */
+               execve (argv[0], argv, env_strings);
+
+               /* set error */
+               _exit (-1);
+
+               break;
+       }
+       default: /* Parent */ {
+               res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle_data);
+               if (!res) {
+                       g_warning ("%s: error looking up process handle %p", __func__, handle);
+                       mono_w32handle_unref (handle);
+               } else {
+                       process_handle_data->id = pid;
+
+                       /* Add our mono_process into the linked list of mono_processes */
+                       mono_process = (MonoProcess *) g_malloc0 (sizeof (MonoProcess));
+                       mono_process->pid = pid;
+                       mono_process->handle_count = 1;
+                       mono_os_sem_init (&mono_process->exit_sem, 0);
+
+                       /* Keep the process handle artificially alive until the process
+                        * exits so that the information in the handle isn't lost. */
+                       mono_w32handle_ref (handle);
+                       mono_process->handle = handle;
+
+                       process_handle_data->mono_process = mono_process;
+
+                       mono_os_mutex_lock (&mono_processes_mutex);
+                       mono_process->next = mono_processes;
+                       mono_processes = mono_process;
+                       mono_os_mutex_unlock (&mono_processes_mutex);
+
+                       if (process_info != NULL) {
+                               process_info->process_handle = handle;
+                               process_info->pid = pid;
+
+                               /* FIXME: we might need to handle the thread info some day */
+                               process_info->thread_handle = INVALID_HANDLE_VALUE;
+                               process_info->tid = 0;
+                       }
+               }
+
+               break;
+       }
+       }
+
+       if (fork_failed)
+               mono_w32handle_unref (handle);
+
+       if (startup_pipe [1] != -1) {
+               /* Write 1 byte, doesn't matter what */
+               ssize_t _i G_GNUC_UNUSED = write (startup_pipe [1], startup_pipe, 1);
+               close (startup_pipe [0]);
+               close (startup_pipe [1]);
+       }
+
+free_strings:
+       if (cmd)
+               g_free (cmd);
+       if (full_prog)
+               g_free (full_prog);
+       if (prog)
+               g_free (prog);
+       if (args)
+               g_free (args);
+       if (dir)
+               g_free (dir);
+       if (env_strings)
+               g_strfreev (env_strings);
+       if (argv)
+               g_strfreev (argv);
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning handle %p for pid %d", __func__, handle, pid);
+
+       /* Check if something needs to be cleaned up. */
+       processes_cleanup ();
+
+       return ret;
+#else
+       SetLastError (ERROR_NOT_SUPPORTED);
+       return FALSE;
+#endif // defined (HAVE_FORK) && defined (HAVE_EXECVE)
+}
+
+MonoBoolean
+ves_icall_System_Diagnostics_Process_ShellExecuteEx_internal (MonoW32ProcessStartInfo *proc_start_info, MonoW32ProcessInfo *process_info)
+{
+       const gunichar2 *lpFile;
+       const gunichar2 *lpParameters;
+       const gunichar2 *lpDirectory;
+       gunichar2 *args;
+       gboolean ret;
+
+       if (!proc_start_info->filename) {
+               /* w2k returns TRUE for this, for some reason. */
+               ret = TRUE;
+               goto done;
+       }
+
+       lpFile = proc_start_info->filename ? mono_string_chars (proc_start_info->filename) : NULL;
+       lpParameters = proc_start_info->arguments ? mono_string_chars (proc_start_info->arguments) : NULL;
+       lpDirectory = proc_start_info->working_directory && mono_string_length (proc_start_info->working_directory) != 0 ?
+               mono_string_chars (proc_start_info->working_directory) : NULL;
+
+       /* Put both executable and parameters into the second argument
+        * to process_create (), so it searches $PATH.  The conversion
+        * into and back out of utf8 is because there is no
+        * g_strdup_printf () equivalent for gunichar2 :-(
+        */
+       args = utf16_concat (utf16_quote, lpFile, utf16_quote, lpParameters == NULL ? NULL : utf16_space, lpParameters, NULL);
+       if (args == NULL) {
+               SetLastError (ERROR_INVALID_DATA);
+               ret = FALSE;
+               goto done;
+       }
+       ret = process_create (NULL, args, NULL, lpDirectory, NULL, process_info);
+       g_free (args);
+
+       if (!ret && GetLastError () == ERROR_OUTOFMEMORY)
+               goto done;
+
+       if (!ret) {
+               static char *handler;
+               static gunichar2 *handler_utf16;
+
+               if (handler_utf16 == (gunichar2 *)-1) {
+                       ret = FALSE;
+                       goto done;
+               }
+
+#ifdef PLATFORM_MACOSX
+               handler = g_strdup ("/usr/bin/open");
+#else
+               /*
+                * On Linux, try: xdg-open, the FreeDesktop standard way of doing it,
+                * if that fails, try to use gnome-open, then kfmclient
+                */
+               handler = g_find_program_in_path ("xdg-open");
+               if (handler == NULL){
+                       handler = g_find_program_in_path ("gnome-open");
+                       if (handler == NULL){
+                               handler = g_find_program_in_path ("kfmclient");
+                               if (handler == NULL){
+                                       handler_utf16 = (gunichar2 *) -1;
+                                       ret = FALSE;
+                                       goto done;
+                               } else {
+                                       /* kfmclient needs exec argument */
+                                       char *old = handler;
+                                       handler = g_strconcat (old, " exec",
+                                                              NULL);
+                                       g_free (old);
+                               }
+                       }
+               }
+#endif
+               handler_utf16 = g_utf8_to_utf16 (handler, -1, NULL, NULL, NULL);
+               g_free (handler);
+
+               /* Put quotes around the filename, in case it's a url
+                * that contains #'s (process_create() calls
+                * g_shell_parse_argv(), which deliberately throws
+                * away anything after an unquoted #).  Fixes bug
+                * 371567.
+                */
+               args = utf16_concat (handler_utf16, utf16_space, utf16_quote, lpFile, utf16_quote,
+                       lpParameters == NULL ? NULL : utf16_space, lpParameters, NULL);
+               if (args == NULL) {
+                       SetLastError (ERROR_INVALID_DATA);
+                       ret = FALSE;
+                       goto done;
+               }
+               ret = process_create (NULL, args, NULL, lpDirectory, NULL, process_info);
+               g_free (args);
+               if (!ret) {
+                       if (GetLastError () != ERROR_OUTOFMEMORY)
+                               SetLastError (ERROR_INVALID_DATA);
+                       ret = FALSE;
+                       goto done;
+               }
+               /* Shell exec should not return a process handle when it spawned a GUI thing, like a browser. */
+               CloseHandle (process_info->process_handle);
+               process_info->process_handle = NULL;
+       }
+
+done:
+       if (ret == FALSE) {
+               process_info->pid = -GetLastError ();
+       } else {
+               process_info->thread_handle = NULL;
+#if !defined(MONO_CROSS_COMPILE)
+               process_info->pid = mono_w32process_get_pid (process_info->process_handle);
+#else
+               process_info->pid = 0;
+#endif
+               process_info->tid = 0;
+       }
+
+       return ret;
+}
+
+/* Only used when UseShellExecute is false */
+static gboolean
+process_get_complete_path (const gunichar2 *appname, gchar **completed)
+{
+       gchar *utf8app;
+       gchar *found;
+
+       utf8app = g_utf16_to_utf8 (appname, -1, NULL, NULL, NULL);
+
+       if (g_path_is_absolute (utf8app)) {
+               *completed = g_shell_quote (utf8app);
+               g_free (utf8app);
+               return TRUE;
+       }
+
+       if (g_file_test (utf8app, G_FILE_TEST_IS_EXECUTABLE) && !g_file_test (utf8app, G_FILE_TEST_IS_DIR)) {
+               *completed = g_shell_quote (utf8app);
+               g_free (utf8app);
+               return TRUE;
+       }
+       
+       found = g_find_program_in_path (utf8app);
+       if (found == NULL) {
+               *completed = NULL;
+               g_free (utf8app);
+               return FALSE;
+       }
+
+       *completed = g_shell_quote (found);
+       g_free (found);
+       g_free (utf8app);
+       return TRUE;
+}
+
+static gboolean
+process_get_shell_arguments (MonoW32ProcessStartInfo *proc_start_info, gunichar2 **shell_path, MonoString **cmd)
+{
+       gchar *spath = NULL;
+
+       *shell_path = NULL;
+       *cmd = proc_start_info->arguments;
+
+       process_get_complete_path (mono_string_chars (proc_start_info->filename), &spath);
+       if (spath != NULL) {
+               *shell_path = g_utf8_to_utf16 (spath, -1, NULL, NULL, NULL);
+               g_free (spath);
+       }
+
+       return (*shell_path != NULL) ? TRUE : FALSE;
+}
+
+MonoBoolean
+ves_icall_System_Diagnostics_Process_CreateProcess_internal (MonoW32ProcessStartInfo *proc_start_info,
+       HANDLE stdin_handle, HANDLE stdout_handle, HANDLE stderr_handle, MonoW32ProcessInfo *process_info)
+{
+       gboolean ret;
+       gunichar2 *dir;
+       StartupHandles startup_handles;
+       gunichar2 *shell_path = NULL;
+       gchar *env_vars = NULL;
+       MonoString *cmd = NULL;
+
+       memset (&startup_handles, 0, sizeof (startup_handles));
+       startup_handles.input = stdin_handle;
+       startup_handles.output = stdout_handle;
+       startup_handles.error = stderr_handle;
+
+       if (process_get_shell_arguments (proc_start_info, &shell_path, &cmd) == FALSE) {
+               process_info->pid = -ERROR_FILE_NOT_FOUND;
+               return FALSE;
+       }
+
+       if (process_info->env_keys) {
+               gint i, len; 
+               MonoString *ms;
+               MonoString *key, *value;
+               gunichar2 *str, *ptr;
+               gunichar2 *equals16;
+
+               for (len = 0, i = 0; i < mono_array_length (process_info->env_keys); i++) {
+                       ms = mono_array_get (process_info->env_values, MonoString *, i);
+                       if (ms == NULL)
+                               continue;
+
+                       len += mono_string_length (ms) * sizeof (gunichar2);
+                       ms = mono_array_get (process_info->env_keys, MonoString *, i);
+                       len += mono_string_length (ms) * sizeof (gunichar2);
+                       len += 2 * sizeof (gunichar2);
+               }
+
+               equals16 = g_utf8_to_utf16 ("=", 1, NULL, NULL, NULL);
+               ptr = str = g_new0 (gunichar2, len + 1);
+               for (i = 0; i < mono_array_length (process_info->env_keys); i++) {
+                       value = mono_array_get (process_info->env_values, MonoString *, i);
+                       if (value == NULL)
+                               continue;
+
+                       key = mono_array_get (process_info->env_keys, MonoString *, i);
+                       memcpy (ptr, mono_string_chars (key), mono_string_length (key) * sizeof (gunichar2));
+                       ptr += mono_string_length (key);
+
+                       memcpy (ptr, equals16, sizeof (gunichar2));
+                       ptr++;
+
+                       memcpy (ptr, mono_string_chars (value), mono_string_length (value) * sizeof (gunichar2));
+                       ptr += mono_string_length (value);
+                       ptr++;
+               }
+
+               g_free (equals16);
+               env_vars = (gchar *) str;
+       }
+       
+       /* The default dir name is "".  Turn that into NULL to mean "current directory" */
+       dir = proc_start_info->working_directory && mono_string_length (proc_start_info->working_directory) > 0 ?
+                       mono_string_chars (proc_start_info->working_directory) : NULL;
+
+       ret = process_create (shell_path, cmd ? mono_string_chars (cmd): NULL, env_vars, dir, &startup_handles, process_info);
+
+       g_free (env_vars);
+       if (shell_path != NULL)
+               g_free (shell_path);
+
+       if (!ret)
+               process_info->pid = -GetLastError ();
+
+       return ret;
+}
+
+/* Returns an array of pids */
+MonoArray *
+ves_icall_System_Diagnostics_Process_GetProcesses_internal (void)
+{
+       MonoError error;
+       MonoArray *procs;
+       gpointer *pidarray;
+       int i, count;
+
+       pidarray = mono_process_list (&count);
+       if (!pidarray) {
+               mono_set_pending_exception (mono_get_exception_not_supported ("This system does not support EnumProcesses"));
+               return NULL;
+       }
+       procs = mono_array_new_checked (mono_domain_get (), mono_get_int32_class (), count, &error);
+       if (mono_error_set_pending_exception (&error)) {
+               g_free (pidarray);
+               return NULL;
+       }
+       if (sizeof (guint32) == sizeof (gpointer)) {
+               memcpy (mono_array_addr (procs, guint32, 0), pidarray, count * sizeof (gint32));
+       } else {
+               for (i = 0; i < count; ++i)
+                       *(mono_array_addr (procs, guint32, i)) = GPOINTER_TO_UINT (pidarray [i]);
+       }
+       g_free (pidarray);
+
+       return procs;
+}
+
+void
+mono_w32process_set_cli_launcher (gchar *path)
+{
+       g_free (cli_launcher);
+       cli_launcher = g_strdup (path);
+}
+
+gpointer
+ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcess (void)
+{
+       mono_w32handle_ref (current_process);
+       return current_process;
+}
+
+MonoBoolean
+ves_icall_Microsoft_Win32_NativeMethods_GetExitCodeProcess (gpointer handle, gint32 *exitcode)
+{
+       MonoW32HandleProcess *process_handle;
+       guint32 pid;
+       gboolean res;
+
+       if (!exitcode)
+               return FALSE;
+
+       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (handle)) {
+               pid = WAPI_HANDLE_TO_PID (handle);
+               /* This is a pseudo handle, so we don't know what the exit
+                * code was, but we can check whether it's alive or not */
+               if (is_pid_valid (pid)) {
+                       *exitcode = STILL_ACTIVE;
+                       return TRUE;
+               } else {
+                       *exitcode = -1;
+                       return TRUE;
+               }
+       }
+
+       res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
+       if (!res) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, handle);
+               return FALSE;
+       }
+
+       if (process_handle->id == wapi_getpid ()) {
+               *exitcode = STILL_ACTIVE;
+               return TRUE;
+       }
+
+       /* A process handle is only signalled if the process has exited
+        * and has been waited for. Make sure any process exit has been
+        * noticed before checking if the process is signalled.
+        * Fixes bug 325463. */
+       mono_w32handle_wait_one (handle, 0, TRUE);
+
+       *exitcode = mono_w32handle_issignalled (handle) ? process_handle->exitstatus : STILL_ACTIVE;
+       return TRUE;
+}
+
+MonoBoolean
+ves_icall_Microsoft_Win32_NativeMethods_CloseProcess (gpointer handle)
+{
+       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (handle))
+               return TRUE;
+       return CloseHandle (handle);
+}
+
+MonoBoolean
+ves_icall_Microsoft_Win32_NativeMethods_TerminateProcess (gpointer handle, gint32 exitcode)
+{
+#ifdef HAVE_KILL
+       MonoW32HandleProcess *process_handle;
+       int ret;
+       pid_t pid;
+
+       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (handle)) {
+               /* This is a pseudo handle */
+               pid = (pid_t)WAPI_HANDLE_TO_PID (handle);
+       } else {
+               gboolean res;
+
+               res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
+               if (!res) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, handle);
+                       SetLastError (ERROR_INVALID_HANDLE);
+                       return FALSE;
+               }
+
+               pid = process_handle->id;
+       }
+
+       ret = kill (pid, exitcode == -1 ? SIGKILL : SIGTERM);
+       if (ret == 0)
+               return TRUE;
+
+       switch (errno) {
+       case EINVAL: SetLastError (ERROR_INVALID_PARAMETER); break;
+       case EPERM:  SetLastError (ERROR_ACCESS_DENIED);     break;
+       case ESRCH:  SetLastError (ERROR_PROC_NOT_FOUND);    break;
+       default:     SetLastError (ERROR_GEN_FAILURE);       break;
+       }
+
+       return FALSE;
+#else
+       g_error ("kill() is not supported by this platform");
+#endif
+}
+
+MonoBoolean
+ves_icall_Microsoft_Win32_NativeMethods_GetProcessWorkingSetSize (gpointer handle, gsize *min, gsize *max)
+{
+       MonoW32HandleProcess *process_handle;
+       gboolean res;
+
+       if (!min || !max)
+               return FALSE;
+
+       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (handle))
+               return FALSE;
+
+       res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
+       if (!res) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, handle);
+               return FALSE;
+       }
+
+       *min = process_handle->min_working_set;
+       *max = process_handle->max_working_set;
+       return TRUE;
+}
+
+MonoBoolean
+ves_icall_Microsoft_Win32_NativeMethods_SetProcessWorkingSetSize (gpointer handle, gsize min, gsize max)
+{
+       MonoW32HandleProcess *process_handle;
+       gboolean res;
+
+       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (handle))
+               return FALSE;
+
+       res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
+       if (!res) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, handle);
+               return FALSE;
+       }
+
+       process_handle->min_working_set = min;
+       process_handle->max_working_set = max;
+       return TRUE;
+}
+
+gint32
+ves_icall_Microsoft_Win32_NativeMethods_GetPriorityClass (gpointer handle)
+{
+#ifdef HAVE_GETPRIORITY
+       MonoW32HandleProcess *process_handle;
+       gint ret;
+       pid_t pid;
+
+       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (handle)) {
+               /* This is a pseudo handle */
+               pid = (pid_t)WAPI_HANDLE_TO_PID (handle);
+       } else {
+               gboolean res;
+
+               res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
+               if (!res) {
+                       SetLastError (ERROR_INVALID_HANDLE);
+                       return 0;
+               }
+
+               pid = process_handle->id;
+       }
+
+       errno = 0;
+       ret = getpriority (PRIO_PROCESS, pid);
+       if (ret == -1 && errno != 0) {
+               switch (errno) {
+               case EPERM:
+               case EACCES:
+                       SetLastError (ERROR_ACCESS_DENIED);
+                       break;
+               case ESRCH:
+                       SetLastError (ERROR_PROC_NOT_FOUND);
+                       break;
+               default:
+                       SetLastError (ERROR_GEN_FAILURE);
+               }
+               return 0;
+       }
+
+       if (ret == 0)
+               return MONO_W32PROCESS_PRIORITY_CLASS_NORMAL;
+       else if (ret < -15)
+               return MONO_W32PROCESS_PRIORITY_CLASS_REALTIME;
+       else if (ret < -10)
+               return MONO_W32PROCESS_PRIORITY_CLASS_HIGH;
+       else if (ret < 0)
+               return MONO_W32PROCESS_PRIORITY_CLASS_ABOVE_NORMAL;
+       else if (ret > 10)
+               return MONO_W32PROCESS_PRIORITY_CLASS_IDLE;
+       else if (ret > 0)
+               return MONO_W32PROCESS_PRIORITY_CLASS_BELOW_NORMAL;
+
+       return MONO_W32PROCESS_PRIORITY_CLASS_NORMAL;
+#else
+       SetLastError (ERROR_NOT_SUPPORTED);
+       return 0;
+#endif
+}
+
+MonoBoolean
+ves_icall_Microsoft_Win32_NativeMethods_SetPriorityClass (gpointer handle, gint32 priorityClass)
+{
+#ifdef HAVE_SETPRIORITY
+       MonoW32HandleProcess *process_handle;
+       int ret;
+       int prio;
+       pid_t pid;
+
+       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (handle)) {
+               /* This is a pseudo handle */
+               pid = (pid_t)WAPI_HANDLE_TO_PID (handle);
+       } else {
+               gboolean res;
+
+               res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
+               if (!res) {
+                       SetLastError (ERROR_INVALID_HANDLE);
+                       return FALSE;
+               }
+
+               pid = process_handle->id;
+       }
+
+       switch (priorityClass) {
+       case MONO_W32PROCESS_PRIORITY_CLASS_IDLE:
+               prio = 19;
+               break;
+       case MONO_W32PROCESS_PRIORITY_CLASS_BELOW_NORMAL:
+               prio = 10;
+               break;
+       case MONO_W32PROCESS_PRIORITY_CLASS_NORMAL:
+               prio = 0;
+               break;
+       case MONO_W32PROCESS_PRIORITY_CLASS_ABOVE_NORMAL:
+               prio = -5;
+               break;
+       case MONO_W32PROCESS_PRIORITY_CLASS_HIGH:
+               prio = -11;
+               break;
+       case MONO_W32PROCESS_PRIORITY_CLASS_REALTIME:
+               prio = -20;
+               break;
+       default:
+               SetLastError (ERROR_INVALID_PARAMETER);
+               return FALSE;
+       }
+
+       ret = setpriority (PRIO_PROCESS, pid, prio);
+       if (ret == -1) {
+               switch (errno) {
+               case EPERM:
+               case EACCES:
+                       SetLastError (ERROR_ACCESS_DENIED);
+                       break;
+               case ESRCH:
+                       SetLastError (ERROR_PROC_NOT_FOUND);
+                       break;
+               default:
+                       SetLastError (ERROR_GEN_FAILURE);
+               }
+       }
+
+       return ret == 0;
+#else
+       SetLastError (ERROR_NOT_SUPPORTED);
+       return FALSE;
+#endif
+}
+
+static void
+ticks_to_processtime (guint64 ticks, ProcessTime *processtime)
+{
+       processtime->lowDateTime = ticks & 0xFFFFFFFF;
+       processtime->highDateTime = ticks >> 32;
+}
+
+static void
+wapifiletime_to_processtime (WapiFileTime wapi_filetime, ProcessTime *processtime)
+{
+       processtime->lowDateTime = wapi_filetime.dwLowDateTime;
+       processtime->highDateTime = wapi_filetime.dwHighDateTime;
+}
+
+MonoBoolean
+ves_icall_Microsoft_Win32_NativeMethods_GetProcessTimes (gpointer handle, gint64 *creation_time, gint64 *exit_time, gint64 *kernel_time, gint64 *user_time)
+{
+       MonoW32HandleProcess *process_handle;
+       ProcessTime *creation_processtime, *exit_processtime, *kernel_processtime, *user_processtime;
+       gboolean res;
+
+       if (!creation_time || !exit_time || !kernel_time || !user_time) {
+               /* Not sure if w32 allows NULLs here or not */
+               return FALSE;
+       }
+
+       creation_processtime = (ProcessTime*) creation_time;
+       exit_processtime = (ProcessTime*) exit_time;
+       kernel_processtime = (ProcessTime*) kernel_time;
+       user_processtime = (ProcessTime*) user_time;
+
+       memset (creation_processtime, 0, sizeof (ProcessTime));
+       memset (exit_processtime, 0, sizeof (ProcessTime));
+       memset (kernel_processtime, 0, sizeof (ProcessTime));
+       memset (user_processtime, 0, sizeof (ProcessTime));
+
+       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (handle)) {
+               gint64 start_ticks, user_ticks, kernel_ticks;
+
+               mono_process_get_times (GINT_TO_POINTER (WAPI_HANDLE_TO_PID (handle)),
+                       &start_ticks, &user_ticks, &kernel_ticks);
+
+               ticks_to_processtime (start_ticks, creation_processtime);
+               ticks_to_processtime (user_ticks, kernel_processtime);
+               ticks_to_processtime (kernel_ticks, user_processtime);
+               return TRUE;
+       }
+
+       res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
+       if (!res) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, handle);
+               return FALSE;
+       }
+
+       wapifiletime_to_processtime (process_handle->create_time, creation_processtime);
+
+       /* A process handle is only signalled if the process has
+        * exited, otherwise exit_processtime isn't set */
+       if (mono_w32handle_issignalled (handle))
+               wapifiletime_to_processtime (process_handle->exit_time, exit_processtime);
+
+#ifdef HAVE_GETRUSAGE
+       if (process_handle->id == getpid ()) {
+               struct rusage time_data;
+               if (getrusage (RUSAGE_SELF, &time_data) == 0) {
+                       ticks_to_processtime ((guint64)time_data.ru_utime.tv_sec * 10000000 + (guint64)time_data.ru_utime.tv_usec * 10, user_processtime);
+                       ticks_to_processtime ((guint64)time_data.ru_stime.tv_sec * 10000000 + (guint64)time_data.ru_stime.tv_usec * 10, kernel_processtime);
+               }
+       }
+#endif
+
+       return TRUE;
+}
diff --git a/mono/metadata/w32process-win32-internals.h b/mono/metadata/w32process-win32-internals.h
new file mode 100644 (file)
index 0000000..1699f95
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#ifndef __MONO_METADATA_PROCESS_INTERNALS_H__
+#define __MONO_METADATA_PROCESS_INTERNALS_H__
+
+#include <config.h>
+#include <glib.h>
+
+// On platforms not using classic WIN API support the  implementation of bellow methods are hosted in separate source file
+// process-windows-*.c. On platforms using classic WIN API the implementation is still keept in process.c and still declared
+// static and in some places even inlined.
+#if !G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+void
+mono_w32process_get_fileversion (MonoObject *filever, gunichar2 *filename, MonoError *error);
+
+void
+mono_process_init_startup_info (HANDLE stdin_handle, HANDLE stdout_handle,
+                               HANDLE stderr_handle,STARTUPINFO *startinfo);
+
+gboolean
+mono_process_create_process (MonoProcInfo *mono_process_info, gunichar2 *shell_path, MonoString *cmd,
+                            guint32 creation_flags, gchar *env_vars, gunichar2 *dir, STARTUPINFO *start_info,
+                            PROCESS_INFORMATION *process_info);
+
+MonoBoolean
+mono_icall_get_process_working_set_size (gpointer handle, gsize *min, gsize *max);
+
+MonoBoolean
+mono_icall_set_process_working_set_size (gpointer handle, gsize min, gsize max);
+
+gint32
+mono_icall_get_priority_class (gpointer handle);
+
+MonoBoolean
+mono_icall_set_priority_class (gpointer handle, gint32 priorityClass);
+#endif  /* !G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+#endif /* __MONO_METADATA_PROCESS_INTERNALS_H__ */
diff --git a/mono/metadata/w32process-win32-uwp.c b/mono/metadata/w32process-win32-uwp.c
new file mode 100644 (file)
index 0000000..9fc329a
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * process-windows-uwp.c: UWP process support for Mono.
+ *
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+*/
+#include <config.h>
+#include <glib.h>
+
+#if G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT)
+#include <Windows.h>
+#include "mono/metadata/w32process-win32-internals.h"
+
+gboolean
+mono_process_win_enum_processes (DWORD *pids, DWORD count, DWORD *needed)
+{
+       g_unsupported_api ("EnumProcesses");
+       *needed = 0;
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return FALSE;
+}
+
+HANDLE
+ves_icall_System_Diagnostics_Process_GetProcess_internal (guint32 pid)
+{
+       HANDLE handle;
+
+       /* GetCurrentProcess returns a pseudo-handle, so use
+        * OpenProcess instead
+        */
+       handle = OpenProcess (PROCESS_ALL_ACCESS, TRUE, pid);
+       if (handle == NULL)
+               /* FIXME: Throw an exception */
+               return NULL;
+       return handle;
+}
+
+void
+mono_w32process_get_fileversion (MonoObject *filever, gunichar2 *filename, MonoError *error)
+{
+       g_unsupported_api ("GetFileVersionInfoSize, GetFileVersionInfo, VerQueryValue, VerLanguageName");
+
+       mono_error_init (error);
+       mono_error_set_not_supported (error, G_UNSUPPORTED_API, "GetFileVersionInfoSize, GetFileVersionInfo, VerQueryValue, VerLanguageName");
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+}
+
+MonoObject*
+process_add_module (HANDLE process, HMODULE mod, gunichar2 *filename, gunichar2 *modulename, MonoClass *proc_class, MonoError *error)
+{
+       g_unsupported_api ("GetModuleInformation");
+
+       mono_error_init (error);
+       mono_error_set_not_supported (error, G_UNSUPPORTED_API, "GetModuleInformation");
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return NULL;
+}
+
+MonoArray *
+ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObject *this_obj, HANDLE process)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("EnumProcessModules, GetModuleBaseName, GetModuleFileNameEx");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "EnumProcessModules, GetModuleBaseName, GetModuleFileNameEx");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return NULL;
+}
+
+MonoBoolean
+ves_icall_System_Diagnostics_Process_ShellExecuteEx_internal (MonoProcessStartInfo *proc_start_info, MonoProcInfo *process_info)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("ShellExecuteEx");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "ShellExecuteEx");
+       mono_error_set_pending_exception (&mono_error);
+
+       process_info->pid = (guint32)(-ERROR_NOT_SUPPORTED);
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return FALSE;
+}
+
+MonoString *
+ves_icall_System_Diagnostics_Process_ProcessName_internal (HANDLE process)
+{
+       MonoError error;
+       MonoString *string;
+       gunichar2 name[MAX_PATH];
+       guint32 len;
+
+       len = GetModuleFileName (NULL, name, G_N_ELEMENTS (name));
+       if (len == 0)
+               return NULL;
+
+       string = mono_string_new_utf16_checked (mono_domain_get (), name, len, &error);
+       if (!mono_error_ok (&error))
+               mono_error_set_pending_exception (&error);
+
+       return string;
+}
+
+void
+mono_process_init_startup_info (HANDLE stdin_handle, HANDLE stdout_handle, HANDLE stderr_handle, STARTUPINFO *startinfo)
+{
+       startinfo->cb = sizeof(STARTUPINFO);
+       startinfo->dwFlags = 0;
+       startinfo->hStdInput = INVALID_HANDLE_VALUE;
+       startinfo->hStdOutput = INVALID_HANDLE_VALUE;
+       startinfo->hStdError = INVALID_HANDLE_VALUE;
+       return;
+}
+
+gboolean
+mono_process_create_process (MonoProcInfo *mono_process_info, gunichar2 *shell_path, MonoString *cmd, guint32 creation_flags,
+                            gchar *env_vars, gunichar2 *dir, STARTUPINFO *start_info, PROCESS_INFORMATION *process_info)
+{
+       MonoError       mono_error;
+       gchar           *api_name = "";
+
+       if (mono_process_info->username) {
+               api_name = "CreateProcessWithLogonW";
+       } else {
+               api_name = "CreateProcess";
+       }
+
+       memset (&process_info, 0, sizeof (PROCESS_INFORMATION));
+       g_unsupported_api (api_name);
+
+       mono_error_init (&mono_error);
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, api_name);
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return FALSE;
+}
+
+MonoBoolean
+mono_icall_get_process_working_set_size (gpointer handle, gsize *min, gsize *max)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("GetProcessWorkingSetSize");
+
+       mono_error_set_not_supported(&mono_error, G_UNSUPPORTED_API, "GetProcessWorkingSetSize");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return FALSE;
+}
+
+MonoBoolean
+mono_icall_set_process_working_set_size (gpointer handle, gsize min, gsize max)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("SetProcessWorkingSetSize");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "SetProcessWorkingSetSize");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return FALSE;
+}
+
+gint32
+mono_icall_get_priority_class (gpointer handle)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("GetPriorityClass");
+
+       mono_error_set_not_supported (&mono_error, G_UNSUPPORTED_API, "GetPriorityClass");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return FALSE;
+}
+
+MonoBoolean
+mono_icall_set_priority_class (gpointer handle, gint32 priorityClass)
+{
+       MonoError mono_error;
+       mono_error_init (&mono_error);
+
+       g_unsupported_api ("SetPriorityClass");
+
+       mono_error_set_not_supported(&mono_error, G_UNSUPPORTED_API, "SetPriorityClass");
+       mono_error_set_pending_exception (&mono_error);
+
+       SetLastError (ERROR_NOT_SUPPORTED);
+
+       return FALSE;
+}
+
+#else /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
+
+#ifdef _MSC_VER
+// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+void __mono_win32_process_windows_uwp_quiet_lnk4221(void) {}
+#endif
+#endif /* G_HAVE_API_SUPPORT(HAVE_UWP_WINAPI_SUPPORT) */
diff --git a/mono/metadata/w32process-win32.c b/mono/metadata/w32process-win32.c
new file mode 100644 (file)
index 0000000..15cfd4d
--- /dev/null
@@ -0,0 +1,500 @@
+/*
+ * process.c: System.Diagnostics.Process support
+ *
+ * Author:
+ *     Dick Porter (dick@ximian.com)
+ *
+ * Copyright 2002 Ximian, Inc.
+ * Copyright 2002-2006 Novell, Inc.
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+
+#include <config.h>
+
+#include <glib.h>
+#include <string.h>
+
+#include <winsock2.h>
+#include <windows.h>
+
+#include <mono/metadata/object-internals.h>
+#include <mono/metadata/w32process.h>
+#include <mono/metadata/w32process-win32-internals.h>
+#include <mono/metadata/assembly.h>
+#include <mono/metadata/appdomain.h>
+#include <mono/metadata/image.h>
+#include <mono/metadata/cil-coff.h>
+#include <mono/metadata/exception.h>
+#include <mono/metadata/threadpool-ms-io.h>
+#include <mono/utils/strenc.h>
+#include <mono/utils/mono-proclib.h>
+#include <mono/io-layer/io-layer.h>
+/* FIXME: fix this code to not depend so much on the internals */
+#include <mono/metadata/class-internals.h>
+#include <mono/metadata/w32handle.h>
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+#include <shellapi.h>
+#endif
+
+void
+mono_w32process_init (void)
+{
+}
+
+void
+mono_w32process_cleanup (void)
+{
+}
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+HANDLE
+ves_icall_System_Diagnostics_Process_GetProcess_internal (guint32 pid)
+{
+       HANDLE handle;
+       
+       /* GetCurrentProcess returns a pseudo-handle, so use
+        * OpenProcess instead
+        */
+       handle = OpenProcess (PROCESS_ALL_ACCESS, TRUE, pid);
+       if (handle == NULL)
+               /* FIXME: Throw an exception */
+               return NULL;
+       return handle;
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT) */
+
+static gchar*
+mono_process_unquote_application_name (gchar *appname)
+{
+       size_t len = strlen (appname);
+       if (len) {
+               if (appname[len-1] == '\"')
+                       appname[len-1] = '\0';
+               if (appname[0] == '\"')
+                       appname++;
+       }
+
+       return appname;
+}
+
+static gchar*
+mono_process_quote_path (const gchar *path)
+{
+       gchar *res = g_shell_quote (path);
+       gchar *q = res;
+       while (*q) {
+               if (*q == '\'')
+                       *q = '\"';
+               q++;
+       }
+       return res;
+}
+
+/* Only used when UseShellExecute is false */
+static gboolean
+mono_process_complete_path (const gunichar2 *appname, gchar **completed)
+{
+       gchar *utf8app, *utf8appmemory;
+       gchar *found;
+
+       utf8appmemory = g_utf16_to_utf8 (appname, -1, NULL, NULL, NULL);
+       utf8app = mono_process_unquote_application_name (utf8appmemory);
+
+       if (g_path_is_absolute (utf8app)) {
+               *completed = mono_process_quote_path (utf8app);
+               g_free (utf8appmemory);
+               return TRUE;
+       }
+
+       if (g_file_test (utf8app, G_FILE_TEST_IS_EXECUTABLE) && !g_file_test (utf8app, G_FILE_TEST_IS_DIR)) {
+               *completed = mono_process_quote_path (utf8app);
+               g_free (utf8appmemory);
+               return TRUE;
+       }
+       
+       found = g_find_program_in_path (utf8app);
+       if (found == NULL) {
+               *completed = NULL;
+               g_free (utf8appmemory);
+               return FALSE;
+       }
+
+       *completed = mono_process_quote_path (found);
+       g_free (found);
+       g_free (utf8appmemory);
+       return TRUE;
+}
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+MonoBoolean
+ves_icall_System_Diagnostics_Process_ShellExecuteEx_internal (MonoW32ProcessStartInfo *proc_start_info, MonoW32ProcessInfo *process_info)
+{
+       SHELLEXECUTEINFO shellex = {0};
+       gboolean ret;
+
+       shellex.cbSize = sizeof(SHELLEXECUTEINFO);
+       shellex.fMask = (gulong)(SEE_MASK_FLAG_DDEWAIT | SEE_MASK_NOCLOSEPROCESS | SEE_MASK_UNICODE);
+       shellex.nShow = (gulong)proc_start_info->window_style;
+       shellex.nShow = (gulong)((shellex.nShow == 0) ? 1 : (shellex.nShow == 1 ? 0 : shellex.nShow));
+
+       if (proc_start_info->filename != NULL) {
+               shellex.lpFile = mono_string_chars (proc_start_info->filename);
+       }
+
+       if (proc_start_info->arguments != NULL) {
+               shellex.lpParameters = mono_string_chars (proc_start_info->arguments);
+       }
+
+       if (proc_start_info->verb != NULL &&
+           mono_string_length (proc_start_info->verb) != 0) {
+               shellex.lpVerb = mono_string_chars (proc_start_info->verb);
+       }
+
+       if (proc_start_info->working_directory != NULL &&
+           mono_string_length (proc_start_info->working_directory) != 0) {
+               shellex.lpDirectory = mono_string_chars (proc_start_info->working_directory);
+       }
+
+       if (proc_start_info->error_dialog) {    
+               shellex.hwnd = proc_start_info->error_dialog_parent_handle;
+       } else {
+               shellex.fMask = (gulong)(shellex.fMask | SEE_MASK_FLAG_NO_UI);
+       }
+
+       ret = ShellExecuteEx (&shellex);
+       if (ret == FALSE) {
+               process_info->pid = -GetLastError ();
+       } else {
+               process_info->process_handle = shellex.hProcess;
+               process_info->thread_handle = NULL;
+#if !defined(MONO_CROSS_COMPILE)
+               process_info->pid = GetProcessId (shellex.hProcess);
+#else
+               process_info->pid = 0;
+#endif
+               process_info->tid = 0;
+       }
+
+       return ret;
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+static inline void
+mono_process_init_startup_info (HANDLE stdin_handle, HANDLE stdout_handle, HANDLE stderr_handle, STARTUPINFO *startinfo)
+{
+       startinfo->cb = sizeof(STARTUPINFO);
+       startinfo->dwFlags = STARTF_USESTDHANDLES;
+       startinfo->hStdInput = stdin_handle;
+       startinfo->hStdOutput = stdout_handle;
+       startinfo->hStdError = stderr_handle;
+       return;
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+static gboolean
+mono_process_create_process (MonoW32ProcessInfo *mono_process_info, gunichar2 *shell_path,
+                            MonoString *cmd, guint32 creation_flags, gchar *env_vars,
+                            gunichar2 *dir, STARTUPINFO *start_info, PROCESS_INFORMATION *process_info)
+{
+       gboolean result = FALSE;
+
+       if (mono_process_info->username) {
+               guint32 logon_flags = mono_process_info->load_user_profile ? LOGON_WITH_PROFILE : 0;
+
+               result = CreateProcessWithLogonW (mono_string_chars (mono_process_info->username),
+                                                 mono_process_info->domain ? mono_string_chars (mono_process_info->domain) : NULL,
+                                                 (const gunichar2 *)mono_process_info->password,
+                                                 logon_flags,
+                                                 shell_path,
+                                                 cmd ? mono_string_chars (cmd) : NULL,
+                                                 creation_flags,
+                                                 env_vars, dir, start_info, process_info);
+
+       } else {
+
+               result = CreateProcess (shell_path,
+                                       cmd ? mono_string_chars (cmd): NULL,
+                                       NULL,
+                                       NULL,
+                                       TRUE,
+                                       creation_flags,
+                                       env_vars,
+                                       dir,
+                                       start_info,
+                                       process_info);
+
+       }
+
+       return result;
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+static gboolean
+mono_process_get_shell_arguments (MonoW32ProcessStartInfo *proc_start_info, gunichar2 **shell_path, MonoString **cmd)
+{
+       gchar           *spath = NULL;
+       gchar           *new_cmd, *cmd_utf8;
+       MonoError       mono_error;
+
+       *shell_path = NULL;
+       *cmd = proc_start_info->arguments;
+
+       mono_process_complete_path (mono_string_chars (proc_start_info->filename), &spath);
+       if (spath != NULL) {
+               /* Seems like our CreateProcess does not work as the windows one.
+                * This hack is needed to deal with paths containing spaces */
+               if (*cmd) {
+                       cmd_utf8 = mono_string_to_utf8_checked (*cmd, &mono_error);
+                       if (!mono_error_set_pending_exception (&mono_error)) {
+                               new_cmd = g_strdup_printf ("%s %s", spath, cmd_utf8);
+                               *cmd = mono_string_new_wrapper (new_cmd);
+                               g_free (cmd_utf8);
+                               g_free (new_cmd);
+                       } else {
+                               *cmd = NULL;
+                       }
+               }
+               else {
+                       *cmd = mono_string_new_wrapper (spath);
+               }
+
+               g_free (spath);
+       }
+
+       return (*cmd != NULL) ? TRUE : FALSE;
+}
+
+MonoBoolean
+ves_icall_System_Diagnostics_Process_CreateProcess_internal (MonoW32ProcessStartInfo *proc_start_info, HANDLE stdin_handle,
+                                                            HANDLE stdout_handle, HANDLE stderr_handle, MonoW32ProcessInfo *process_info)
+{
+       gboolean ret;
+       gunichar2 *dir;
+       STARTUPINFO startinfo={0};
+       PROCESS_INFORMATION procinfo;
+       gunichar2 *shell_path = NULL;
+       gchar *env_vars = NULL;
+       MonoString *cmd = NULL;
+       guint32 creation_flags;
+
+       mono_process_init_startup_info (stdin_handle, stdout_handle, stderr_handle, &startinfo);
+
+       creation_flags = CREATE_UNICODE_ENVIRONMENT;
+       if (proc_start_info->create_no_window)
+               creation_flags |= CREATE_NO_WINDOW;
+       
+       if (mono_process_get_shell_arguments (proc_start_info, &shell_path, &cmd) == FALSE) {
+               process_info->pid = -ERROR_FILE_NOT_FOUND;
+               return FALSE;
+       }
+
+       if (process_info->env_keys) {
+               gint i, len; 
+               MonoString *ms;
+               MonoString *key, *value;
+               gunichar2 *str, *ptr;
+               gunichar2 *equals16;
+
+               for (len = 0, i = 0; i < mono_array_length (process_info->env_keys); i++) {
+                       ms = mono_array_get (process_info->env_values, MonoString *, i);
+                       if (ms == NULL)
+                               continue;
+
+                       len += mono_string_length (ms) * sizeof (gunichar2);
+                       ms = mono_array_get (process_info->env_keys, MonoString *, i);
+                       len += mono_string_length (ms) * sizeof (gunichar2);
+                       len += 2 * sizeof (gunichar2);
+               }
+
+               equals16 = g_utf8_to_utf16 ("=", 1, NULL, NULL, NULL);
+               ptr = str = g_new0 (gunichar2, len + 1);
+               for (i = 0; i < mono_array_length (process_info->env_keys); i++) {
+                       value = mono_array_get (process_info->env_values, MonoString *, i);
+                       if (value == NULL)
+                               continue;
+
+                       key = mono_array_get (process_info->env_keys, MonoString *, i);
+                       memcpy (ptr, mono_string_chars (key), mono_string_length (key) * sizeof (gunichar2));
+                       ptr += mono_string_length (key);
+
+                       memcpy (ptr, equals16, sizeof (gunichar2));
+                       ptr++;
+
+                       memcpy (ptr, mono_string_chars (value), mono_string_length (value) * sizeof (gunichar2));
+                       ptr += mono_string_length (value);
+                       ptr++;
+               }
+
+               g_free (equals16);
+               env_vars = (gchar *) str;
+       }
+       
+       /* The default dir name is "".  Turn that into NULL to mean
+        * "current directory"
+        */
+       if (proc_start_info->working_directory == NULL || mono_string_length (proc_start_info->working_directory) == 0)
+               dir = NULL;
+       else
+               dir = mono_string_chars (proc_start_info->working_directory);
+
+       ret = mono_process_create_process (process_info, shell_path, cmd, creation_flags, env_vars, dir, &startinfo, &procinfo);
+
+       g_free (env_vars);
+       if (shell_path != NULL)
+               g_free (shell_path);
+
+       if (ret) {
+               process_info->process_handle = procinfo.hProcess;
+               /*process_info->thread_handle=procinfo.hThread;*/
+               process_info->thread_handle = NULL;
+               if (procinfo.hThread != NULL && procinfo.hThread != INVALID_HANDLE_VALUE)
+                       CloseHandle (procinfo.hThread);
+               process_info->pid = procinfo.dwProcessId;
+               process_info->tid = procinfo.dwThreadId;
+       } else {
+               process_info->pid = -GetLastError ();
+       }
+       
+       return ret;
+}
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+static inline gboolean
+mono_process_win_enum_processes (DWORD *pids, DWORD count, DWORD *needed)
+{
+       return EnumProcesses (pids, count, needed);
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+MonoArray *
+ves_icall_System_Diagnostics_Process_GetProcesses_internal (void)
+{
+       MonoError error;
+       MonoArray *procs;
+       gboolean ret;
+       DWORD needed;
+       int count;
+       DWORD *pids;
+
+       count = 512;
+       do {
+               pids = g_new0 (DWORD, count);
+               ret = mono_process_win_enum_processes (pids, count * sizeof (guint32), &needed);
+               if (ret == FALSE) {
+                       MonoException *exc;
+
+                       g_free (pids);
+                       pids = NULL;
+                       exc = mono_get_exception_not_supported ("This system does not support EnumProcesses");
+                       mono_set_pending_exception (exc);
+                       return NULL;
+               }
+               if (needed < (count * sizeof (guint32)))
+                       break;
+               g_free (pids);
+               pids = NULL;
+               count = (count * 3) / 2;
+       } while (TRUE);
+
+       count = needed / sizeof (guint32);
+       procs = mono_array_new_checked (mono_domain_get (), mono_get_int32_class (), count, &error);
+       if (mono_error_set_pending_exception (&error)) {
+               g_free (pids);
+               return NULL;
+       }
+
+       memcpy (mono_array_addr (procs, guint32, 0), pids, needed);
+       g_free (pids);
+       pids = NULL;
+
+       return procs;
+}
+
+MonoBoolean
+ves_icall_Microsoft_Win32_NativeMethods_CloseProcess (gpointer handle)
+{
+       return CloseHandle (handle);
+}
+
+MonoBoolean
+ves_icall_Microsoft_Win32_NativeMethods_TerminateProcess (gpointer handle, gint32 exitcode)
+{
+       return TerminateProcess (handle, exitcode);
+}
+
+MonoBoolean
+ves_icall_Microsoft_Win32_NativeMethods_GetExitCodeProcess (gpointer handle, gint32 *exitcode)
+{
+       return GetExitCodeProcess (handle, exitcode);
+}
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+static inline MonoBoolean
+mono_icall_get_process_working_set_size (gpointer handle, gsize *min, gsize *max)
+{
+       return GetProcessWorkingSetSize (handle, min, max);
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+MonoBoolean
+ves_icall_Microsoft_Win32_NativeMethods_GetProcessWorkingSetSize (gpointer handle, gsize *min, gsize *max)
+{
+       return mono_icall_get_process_working_set_size (handle, min, max);
+}
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+static inline MonoBoolean
+mono_icall_set_process_working_set_size (gpointer handle, gsize min, gsize max)
+{
+       return SetProcessWorkingSetSize (handle, min, max);
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+MonoBoolean
+ves_icall_Microsoft_Win32_NativeMethods_SetProcessWorkingSetSize (gpointer handle, gsize min, gsize max)
+{
+       return mono_icall_set_process_working_set_size (handle, min, max);
+}
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+static inline gint32
+mono_icall_get_priority_class (gpointer handle)
+{
+       return GetPriorityClass (handle);
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+gint32
+ves_icall_Microsoft_Win32_NativeMethods_GetPriorityClass (gpointer handle)
+{
+       return mono_icall_get_priority_class (handle);
+}
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+static inline MonoBoolean
+mono_icall_set_priority_class (gpointer handle, gint32 priorityClass)
+{
+       return SetPriorityClass (handle, (guint32) priorityClass);
+}
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+MonoBoolean
+ves_icall_Microsoft_Win32_NativeMethods_SetPriorityClass (gpointer handle, gint32 priorityClass)
+{
+       return mono_icall_set_priority_class (handle, priorityClass);
+}
+
+MonoBoolean
+ves_icall_Microsoft_Win32_NativeMethods_GetProcessTimes (gpointer handle, gint64 *creationtime, gint64 *exittime, gint64 *kerneltime, gint64 *usertime)
+{
+       return GetProcessTimes (handle, (LPFILETIME) creationtime, (LPFILETIME) exittime, (LPFILETIME) kerneltime, (LPFILETIME) usertime);
+}
+
+gpointer
+ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcess (void)
+{
+       return GetCurrentProcess ();
+}
diff --git a/mono/metadata/w32process.c b/mono/metadata/w32process.c
new file mode 100644 (file)
index 0000000..614168e
--- /dev/null
@@ -0,0 +1,624 @@
+
+#include <glib.h>
+
+#include "w32process.h"
+#include "w32process-internals.h"
+#include "w32process-win32-internals.h"
+#include "object.h"
+#include "object-internals.h"
+#include "class.h"
+#include "class-internals.h"
+#include "image.h"
+#include "utils/mono-proclib.h"
+
+#define LOGDEBUG(...)
+/* define LOGDEBUG(...) g_message(__VA_ARGS__)  */
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) && defined(HOST_WIN32)
+
+static guint32
+mono_w32process_get_pid (gpointer handle)
+{
+       return GetProcessId (handle);
+}
+
+static gboolean
+mono_w32process_try_get_modules (gpointer process, gpointer *modules, guint32 size, guint32 *needed)
+{
+       return EnumProcessModules (process, (HMODULE *) modules, size, (LPDWORD) needed);
+}
+
+static guint32
+mono_w32process_module_get_name (gpointer process, gpointer module, gunichar2 *basename, guint32 size)
+{
+       return GetModuleBaseName (process, module, basename, size);
+}
+
+static guint32
+mono_w32process_module_get_filename (gpointer process, gpointer module, gunichar2 *basename, guint32 size)
+{
+       return GetModuleFileNameEx (process, module, basename, size);
+}
+
+static gboolean
+mono_w32process_module_get_information (gpointer process, gpointer module, MODULEINFO *modinfo, guint32 size)
+{
+       return GetModuleInformation (process, module, modinfo, size);
+}
+
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) && defined(HOST_WIN32) */
+
+static MonoImage *system_image;
+
+static void
+stash_system_image (MonoImage *image)
+{
+       system_image = image;
+}
+
+static MonoClass*
+get_file_version_info_class (void)
+{
+       static MonoClass *file_version_info_class;
+
+       if (file_version_info_class)
+               return file_version_info_class;
+
+       g_assert (system_image);
+
+       return file_version_info_class = mono_class_load_from_name (
+               system_image, "System.Diagnostics", "FileVersionInfo");
+}
+
+static MonoClass*
+get_process_module_class (void)
+{
+       static MonoClass *process_module_class;
+
+       if (process_module_class)
+               return process_module_class;
+
+       g_assert (system_image);
+
+       return process_module_class = mono_class_load_from_name (
+               system_image, "System.Diagnostics", "ProcessModule");
+}
+
+static guint32
+unicode_chars (const gunichar2 *str)
+{
+       guint32 len;
+       for (len = 0; str [len] != '\0'; ++len) {}
+       return len;
+}
+
+static void
+process_set_field_object (MonoObject *obj, const gchar *fieldname, MonoObject *data)
+{
+       MonoClass *klass;
+       MonoClassField *field;
+
+       LOGDEBUG (g_message ("%s: Setting field %s to object at %p", __func__, fieldname, data));
+
+       klass = mono_object_class (obj);
+       g_assert (klass);
+
+       field = mono_class_get_field_from_name (klass, fieldname);
+       g_assert (field);
+
+       mono_gc_wbarrier_generic_store (((char *)obj) + field->offset, data);
+}
+
+static void
+process_set_field_string (MonoObject *obj, const gchar *fieldname, const gunichar2 *val, guint32 len, MonoError *error)
+{
+       MonoDomain *domain;
+       MonoClass *klass;
+       MonoClassField *field;
+       MonoString *string;
+
+       mono_error_init (error);
+
+       LOGDEBUG (g_message ("%s: Setting field %s to [%s]", __func__, fieldname, g_utf16_to_utf8 (val, len, NULL, NULL, NULL)));
+
+       domain = mono_object_domain (obj);
+       g_assert (domain);
+
+       klass = mono_object_class (obj);
+       g_assert (klass);
+
+       field = mono_class_get_field_from_name (klass, fieldname);
+       g_assert (field);
+
+       string = mono_string_new_utf16_checked (domain, val, len, error);
+       return_if_nok (error);
+
+       mono_gc_wbarrier_generic_store (((char *)obj) + field->offset, (MonoObject*)string);
+}
+
+static void
+process_set_field_string_char (MonoObject *obj, const gchar *fieldname, const gchar *val)
+{
+       MonoDomain *domain;
+       MonoClass *klass;
+       MonoClassField *field;
+       MonoString *string;
+
+       LOGDEBUG (g_message ("%s: Setting field %s to [%s]", __func__, fieldname, val));
+
+       domain = mono_object_domain (obj);
+       g_assert (domain);
+
+       klass = mono_object_class (obj);
+       g_assert (klass);
+
+       field = mono_class_get_field_from_name (klass, fieldname);
+       g_assert (field);
+
+       string = mono_string_new (domain, val);
+
+       mono_gc_wbarrier_generic_store (((char *)obj) + field->offset, (MonoObject*)string);
+}
+
+static void
+process_set_field_int (MonoObject *obj, const gchar *fieldname, guint32 val)
+{
+       MonoClass *klass;
+       MonoClassField *field;
+
+       LOGDEBUG (g_message ("%s: Setting field %s to %d", __func__,fieldname, val));
+
+       klass = mono_object_class (obj);
+       g_assert (klass);
+
+       field = mono_class_get_field_from_name (klass, fieldname);
+       g_assert (field);
+
+       *(guint32 *)(((char *)obj) + field->offset)=val;
+}
+
+static void
+process_set_field_intptr (MonoObject *obj, const gchar *fieldname, gpointer val)
+{
+       MonoClass *klass;
+       MonoClassField *field;
+
+       LOGDEBUG (g_message ("%s: Setting field %s to %p", __func__, fieldname, val));
+
+       klass = mono_object_class (obj);
+       g_assert (klass);
+
+       field = mono_class_get_field_from_name (klass, fieldname);
+       g_assert (field);
+
+       *(gpointer *)(((char *)obj) + field->offset) = val;
+}
+
+static void
+process_set_field_bool (MonoObject *obj, const gchar *fieldname, gboolean val)
+{
+       MonoClass *klass;
+       MonoClassField *field;
+
+       LOGDEBUG (g_message ("%s: Setting field %s to %s", __func__, fieldname, val ? "TRUE":"FALSE"));
+
+       klass = mono_object_class (obj);
+       g_assert (klass);
+
+       field = mono_class_get_field_from_name (klass, fieldname);
+       g_assert (field);
+
+       *(guint8 *)(((char *)obj) + field->offset) = val;
+}
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+
+#define SFI_COMMENTS           "\\StringFileInfo\\%02X%02X%02X%02X\\Comments"
+#define SFI_COMPANYNAME                "\\StringFileInfo\\%02X%02X%02X%02X\\CompanyName"
+#define SFI_FILEDESCRIPTION    "\\StringFileInfo\\%02X%02X%02X%02X\\FileDescription"
+#define SFI_FILEVERSION                "\\StringFileInfo\\%02X%02X%02X%02X\\FileVersion"
+#define SFI_INTERNALNAME       "\\StringFileInfo\\%02X%02X%02X%02X\\InternalName"
+#define SFI_LEGALCOPYRIGHT     "\\StringFileInfo\\%02X%02X%02X%02X\\LegalCopyright"
+#define SFI_LEGALTRADEMARKS    "\\StringFileInfo\\%02X%02X%02X%02X\\LegalTrademarks"
+#define SFI_ORIGINALFILENAME   "\\StringFileInfo\\%02X%02X%02X%02X\\OriginalFilename"
+#define SFI_PRIVATEBUILD       "\\StringFileInfo\\%02X%02X%02X%02X\\PrivateBuild"
+#define SFI_PRODUCTNAME                "\\StringFileInfo\\%02X%02X%02X%02X\\ProductName"
+#define SFI_PRODUCTVERSION     "\\StringFileInfo\\%02X%02X%02X%02X\\ProductVersion"
+#define SFI_SPECIALBUILD       "\\StringFileInfo\\%02X%02X%02X%02X\\SpecialBuild"
+#define EMPTY_STRING           (gunichar2*)"\000\000"
+
+typedef struct {
+       const char *name;
+       const char *id;
+} StringTableEntry;
+
+static StringTableEntry stringtable_entries [] = {
+       { "comments", SFI_COMMENTS },
+       { "companyname", SFI_COMPANYNAME },
+       { "filedescription", SFI_FILEDESCRIPTION },
+       { "fileversion", SFI_FILEVERSION },
+       { "internalname", SFI_INTERNALNAME },
+       { "legalcopyright", SFI_LEGALCOPYRIGHT },
+       { "legaltrademarks", SFI_LEGALTRADEMARKS },
+       { "originalfilename", SFI_ORIGINALFILENAME },
+       { "privatebuild", SFI_PRIVATEBUILD },
+       { "productname", SFI_PRODUCTNAME },
+       { "productversion", SFI_PRODUCTVERSION },
+       { "specialbuild", SFI_SPECIALBUILD }
+};
+
+static void
+process_module_string_read (MonoObject *filever, gpointer data, const gchar *fieldname,
+               guchar lang_hi, guchar lang_lo, const gchar *key, MonoError *error)
+{
+       gchar *lang_key_utf8;
+       gunichar2 *lang_key, *buffer;
+       UINT chars;
+
+       mono_error_init (error);
+
+       lang_key_utf8 = g_strdup_printf (key, lang_lo, lang_hi, 0x04, 0xb0);
+
+       LOGDEBUG (g_message ("%s: asking for [%s]", __func__, lang_key_utf8));
+
+       lang_key = g_utf8_to_utf16 (lang_key_utf8, -1, NULL, NULL, NULL);
+
+       if (VerQueryValue (data, lang_key, (gpointer *)&buffer, &chars) && chars > 0) {
+               LOGDEBUG (g_message ("%s: found %d chars of [%s]", __func__, chars, g_utf16_to_utf8 (buffer, chars, NULL, NULL, NULL)));
+               /* chars includes trailing null */
+               process_set_field_string (filever, fieldname, buffer, chars - 1, error);
+       } else {
+               process_set_field_string (filever, fieldname, EMPTY_STRING, 0, error);
+       }
+
+       g_free (lang_key);
+       g_free (lang_key_utf8);
+}
+
+static void
+process_module_stringtable (MonoObject *filever, gpointer data, guchar lang_hi, guchar lang_lo, MonoError *error)
+{
+       for (int i = 0; i < G_N_ELEMENTS (stringtable_entries); ++i) {
+               process_module_string_read (filever, data, stringtable_entries [i].name,
+                       lang_hi, lang_lo, stringtable_entries [i].id, error);
+               return_if_nok (error);
+       }
+}
+
+static void
+mono_w32process_get_fileversion (MonoObject *filever, gunichar2 *filename, MonoError *error)
+{
+       DWORD verinfohandle;
+       VS_FIXEDFILEINFO *ffi;
+       gpointer data;
+       DWORD datalen;
+       guchar *trans_data;
+       gunichar2 *query;
+       UINT ffi_size, trans_size;
+       BOOL ok;
+       gunichar2 lang_buf[128];
+       guint32 lang, lang_count;
+
+       mono_error_init (error);
+
+       datalen = GetFileVersionInfoSize (filename, &verinfohandle);
+       if (datalen) {
+               data = g_malloc0 (datalen);
+               ok = GetFileVersionInfo (filename, verinfohandle, datalen, data);
+               if (ok) {
+                       query = g_utf8_to_utf16 ("\\", -1, NULL, NULL, NULL);
+                       if (query == NULL) {
+                               g_free (data);
+                               return;
+                       }
+
+                       if (VerQueryValue (data, query, (gpointer *)&ffi, &ffi_size)) {
+                               LOGDEBUG (g_message ("%s: recording assembly: FileName [%s] FileVersionInfo [%d.%d.%d.%d]", __func__, g_utf16_to_utf8 (filename, -1, NULL, NULL, NULL), HIWORD (ffi->dwFileVersionMS), LOWORD (ffi->dwFileVersionMS), HIWORD (ffi->dwFileVersionLS), LOWORD (ffi->dwFileVersionLS)));
+
+                               process_set_field_int (filever, "filemajorpart", HIWORD (ffi->dwFileVersionMS));
+                               process_set_field_int (filever, "fileminorpart", LOWORD (ffi->dwFileVersionMS));
+                               process_set_field_int (filever, "filebuildpart", HIWORD (ffi->dwFileVersionLS));
+                               process_set_field_int (filever, "fileprivatepart", LOWORD (ffi->dwFileVersionLS));
+
+                               process_set_field_int (filever, "productmajorpart", HIWORD (ffi->dwProductVersionMS));
+                               process_set_field_int (filever, "productminorpart", LOWORD (ffi->dwProductVersionMS));
+                               process_set_field_int (filever, "productbuildpart", HIWORD (ffi->dwProductVersionLS));
+                               process_set_field_int (filever, "productprivatepart", LOWORD (ffi->dwProductVersionLS));
+
+                               process_set_field_bool (filever, "isdebug", ((ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_DEBUG) != 0);
+                               process_set_field_bool (filever, "isprerelease", ((ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_PRERELEASE) != 0);
+                               process_set_field_bool (filever, "ispatched", ((ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_PATCHED) != 0);
+                               process_set_field_bool (filever, "isprivatebuild", ((ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_PRIVATEBUILD) != 0);
+                               process_set_field_bool (filever, "isspecialbuild", ((ffi->dwFileFlags & ffi->dwFileFlagsMask) & VS_FF_SPECIALBUILD) != 0);
+                       }
+                       g_free (query);
+
+                       query = g_utf8_to_utf16 ("\\VarFileInfo\\Translation", -1, NULL, NULL, NULL);
+                       if (query == NULL) {
+                               g_free (data);
+                               return;
+                       }
+
+                       if (VerQueryValue (data, query, (gpointer *)&trans_data, &trans_size)) {
+                               /* use the first language ID we see */
+                               if (trans_size >= 4) {
+                                       LOGDEBUG (g_message("%s: %s has 0x%0x 0x%0x 0x%0x 0x%0x", __func__, g_utf16_to_utf8 (filename, -1, NULL, NULL, NULL), trans_data[0], trans_data[1], trans_data[2], trans_data[3]));
+                                       lang = (trans_data[0]) | (trans_data[1] << 8) | (trans_data[2] << 16) | (trans_data[3] << 24);
+                                       /* Only give the lower 16 bits to VerLanguageName, as Windows gets confused otherwise  */
+                                       lang_count = VerLanguageName (lang & 0xFFFF, lang_buf, 128);
+                                       if (lang_count) {
+                                               process_set_field_string (filever, "language", lang_buf, lang_count, error);
+                                               return_if_nok (error);
+                                       }
+                                       process_module_stringtable (filever, data, trans_data[0], trans_data[1], error);
+                                       return_if_nok (error);
+                               }
+                       } else {
+                               int i;
+
+                               for (i = 0; i < G_N_ELEMENTS (stringtable_entries); ++i) {
+                                       /* No strings, so set every field to the empty string */
+                                       process_set_field_string (filever, stringtable_entries [i].name, EMPTY_STRING, 0, error);
+                                       return_if_nok (error);
+                               }
+
+                               /* And language seems to be set to en_US according to bug 374600 */
+                               lang_count = VerLanguageName (0x0409, lang_buf, 128);
+                               if (lang_count) {
+                                       process_set_field_string (filever, "language", lang_buf, lang_count, error);
+                                       return_if_nok (error);
+                               }
+                       }
+
+                       g_free (query);
+               }
+               g_free (data);
+       }
+}
+
+#endif /* #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+void
+ves_icall_System_Diagnostics_FileVersionInfo_GetVersionInfo_internal (MonoObject *this_obj, MonoString *filename)
+{
+       MonoError error;
+
+       stash_system_image (mono_object_class (this_obj)->image);
+
+       mono_w32process_get_fileversion (this_obj, mono_string_chars (filename), &error);
+       if (!mono_error_ok (&error)) {
+               mono_error_set_pending_exception (&error);
+               return;
+       }
+
+       process_set_field_string (this_obj, "filename", mono_string_chars (filename), mono_string_length (filename), &error);
+       if (!mono_error_ok (&error)) {
+               mono_error_set_pending_exception (&error);
+       }
+}
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+
+static GPtrArray*
+get_domain_assemblies (MonoDomain *domain)
+{
+       GSList *tmp;
+       GPtrArray *assemblies;
+
+       /*
+        * Make a copy of the list of assemblies because we can't hold the assemblies
+        * lock while creating objects etc.
+        */
+       assemblies = g_ptr_array_new ();
+       mono_domain_assemblies_lock (domain);
+       for (tmp = domain->domain_assemblies; tmp; tmp = tmp->next) {
+               MonoAssembly *ass = (MonoAssembly *)tmp->data;
+               if (ass->image->fileio_used)
+                       continue;
+               g_ptr_array_add (assemblies, ass);
+       }
+       mono_domain_assemblies_unlock (domain);
+
+       return assemblies;
+}
+
+static MonoObject*
+process_add_module (HANDLE process, HMODULE mod, gunichar2 *filename, gunichar2 *modulename, MonoClass *proc_class, MonoError *error)
+{
+       MonoObject *item, *filever;
+       MonoDomain *domain = mono_domain_get ();
+       MODULEINFO modinfo;
+       BOOL ok;
+
+       mono_error_init (error);
+
+       /* Build a System.Diagnostics.ProcessModule with the data. */
+       item = mono_object_new_checked (domain, proc_class, error);
+       return_val_if_nok (error, NULL);
+
+       filever = mono_object_new_checked (domain, get_file_version_info_class (), error);
+       return_val_if_nok (error, NULL);
+
+       mono_w32process_get_fileversion (filever, filename, error);
+       return_val_if_nok (error, NULL);
+
+       process_set_field_string (filever, "filename", filename, unicode_chars (filename), error);
+       return_val_if_nok (error, NULL);
+
+       ok = mono_w32process_module_get_information (process, mod, &modinfo, sizeof(MODULEINFO));
+       if (ok) {
+               process_set_field_intptr (item, "baseaddr", modinfo.lpBaseOfDll);
+               process_set_field_intptr (item, "entryaddr", modinfo.EntryPoint);
+               process_set_field_int (item, "memory_size", modinfo.SizeOfImage);
+       }
+
+       process_set_field_string (item, "filename", filename, unicode_chars (filename), error);
+       return_val_if_nok (error, NULL);
+
+       process_set_field_string (item, "modulename", modulename, unicode_chars (modulename), error);
+       return_val_if_nok (error, NULL);
+
+       process_set_field_object (item, "version_info", filever);
+
+       return item;
+}
+
+static void
+process_get_assembly_fileversion (MonoObject *filever, MonoAssembly *assembly)
+{
+       process_set_field_int (filever, "filemajorpart", assembly->aname.major);
+       process_set_field_int (filever, "fileminorpart", assembly->aname.minor);
+       process_set_field_int (filever, "filebuildpart", assembly->aname.build);
+}
+
+static MonoObject*
+process_get_module (MonoAssembly *assembly, MonoClass *proc_class, MonoError *error)
+{
+       MonoObject *item, *filever;
+       MonoDomain *domain;
+       gchar *filename;
+       const gchar *modulename;
+
+       mono_error_init (error);
+
+       domain = mono_domain_get ();
+
+       modulename = assembly->aname.name;
+
+       /* Build a System.Diagnostics.ProcessModule with the data. */
+       item = mono_object_new_checked (domain, proc_class, error);
+       return_val_if_nok (error, NULL);
+
+       filever = mono_object_new_checked (domain, get_file_version_info_class (), error);
+       return_val_if_nok (error, NULL);
+
+       filename = g_strdup_printf ("[In Memory] %s", modulename);
+
+       process_get_assembly_fileversion (filever, assembly);
+       process_set_field_string_char (filever, "filename", filename);
+       process_set_field_object (item, "version_info", filever);
+
+       process_set_field_intptr (item, "baseaddr", assembly->image->raw_data);
+       process_set_field_int (item, "memory_size", assembly->image->raw_data_len);
+       process_set_field_string_char (item, "filename", filename);
+       process_set_field_string_char (item, "modulename", modulename);
+
+       g_free (filename);
+
+       return item;
+}
+
+/* Returns an array of System.Diagnostics.ProcessModule */
+MonoArray *
+ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObject *this_obj, HANDLE process)
+{
+       MonoError error;
+       MonoArray *temp_arr = NULL;
+       MonoArray *arr;
+       HMODULE mods[1024];
+       gunichar2 filename[MAX_PATH];
+       gunichar2 modname[MAX_PATH];
+       DWORD needed;
+       guint32 count = 0, module_count = 0, assembly_count = 0;
+       guint32 i, num_added = 0;
+       GPtrArray *assemblies = NULL;
+
+       stash_system_image (mono_object_class (this_obj)->image);
+
+       if (mono_w32process_get_pid (process) == mono_process_current_pid ()) {
+               assemblies = get_domain_assemblies (mono_domain_get ());
+               assembly_count = assemblies->len;
+       }
+
+       if (mono_w32process_try_get_modules (process, mods, sizeof(mods), &needed))
+               module_count += needed / sizeof(HMODULE);
+
+       count = module_count + assembly_count;
+       temp_arr = mono_array_new_checked (mono_domain_get (), get_process_module_class (), count, &error);
+       if (mono_error_set_pending_exception (&error))
+               return NULL;
+
+       for (i = 0; i < module_count; i++) {
+               if (mono_w32process_module_get_name (process, mods[i], modname, MAX_PATH)
+                        && mono_w32process_module_get_filename (process, mods[i], filename, MAX_PATH))
+               {
+                       MonoObject *module = process_add_module (process, mods[i], filename, modname, get_process_module_class (), &error);
+                       if (!mono_error_ok (&error)) {
+                               mono_error_set_pending_exception (&error);
+                               return NULL;
+                       }
+                       mono_array_setref (temp_arr, num_added++, module);
+               }
+       }
+
+       if (assemblies) {
+               for (i = 0; i < assembly_count; i++) {
+                       MonoAssembly *ass = (MonoAssembly *)g_ptr_array_index (assemblies, i);
+                       MonoObject *module = process_get_module (ass, get_process_module_class (), &error);
+                       if (!mono_error_ok (&error)) {
+                               mono_error_set_pending_exception (&error);
+                               return NULL;
+                       }
+                       mono_array_setref (temp_arr, num_added++, module);
+               }
+               g_ptr_array_free (assemblies, TRUE);
+       }
+
+       if (count == num_added) {
+               arr = temp_arr;
+       } else {
+               /* shorter version of the array */
+               arr = mono_array_new_checked (mono_domain_get (), get_process_module_class (), num_added, &error);
+               if (mono_error_set_pending_exception (&error))
+                       return NULL;
+
+               for (i = 0; i < num_added; i++)
+                       mono_array_setref (arr, i, mono_array_get (temp_arr, MonoObject*, i));
+       }
+
+       return arr;
+}
+
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+#if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
+
+MonoString *
+ves_icall_System_Diagnostics_Process_ProcessName_internal (HANDLE process)
+{
+       MonoError error;
+       MonoString *string;
+       gunichar2 name[MAX_PATH];
+       guint32 len;
+       gboolean ok;
+       HMODULE mod;
+       DWORD needed;
+
+       ok = mono_w32process_try_get_modules (process, &mod, sizeof(mod), &needed);
+       if (!ok)
+               return NULL;
+
+       len = mono_w32process_module_get_name (process, mod, name, MAX_PATH);
+       if (len == 0)
+               return NULL;
+
+       string = mono_string_new_utf16_checked (mono_domain_get (), name, len, &error);
+       if (!mono_error_ok (&error))
+               mono_error_set_pending_exception (&error);
+
+       return string;
+}
+
+#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
+
+gint64
+ves_icall_System_Diagnostics_Process_GetProcessData (int pid, gint32 data_type, gint32 *error)
+{
+       MonoProcessError perror;
+       guint64 res;
+
+       res = mono_process_get_data_with_error (GINT_TO_POINTER (pid), (MonoProcessData)data_type, &perror);
+       if (error)
+               *error = perror;
+       return res;
+}
diff --git a/mono/metadata/w32process.h b/mono/metadata/w32process.h
new file mode 100644 (file)
index 0000000..7df9caf
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * w32process.h: System.Diagnostics.Process support
+ *
+ * Author:
+ *     Dick Porter (dick@ximian.com)
+ *
+ * (C) 2002 Ximian, Inc.
+ */
+
+#ifndef _MONO_METADATA_W32PROCESS_H_
+#define _MONO_METADATA_W32PROCESS_H_
+
+#include <config.h>
+#include <glib.h>
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include <mono/metadata/object.h>
+
+G_BEGIN_DECLS
+
+typedef enum {
+       MONO_W32PROCESS_PRIORITY_CLASS_NORMAL       = 0x0020,
+       MONO_W32PROCESS_PRIORITY_CLASS_IDLE         = 0x0040,
+       MONO_W32PROCESS_PRIORITY_CLASS_HIGH         = 0x0080,
+       MONO_W32PROCESS_PRIORITY_CLASS_REALTIME     = 0x0100,
+       MONO_W32PROCESS_PRIORITY_CLASS_BELOW_NORMAL = 0x4000,
+       MONO_W32PROCESS_PRIORITY_CLASS_ABOVE_NORMAL = 0x8000,
+} MonoW32ProcessPriorityClass;
+
+typedef struct 
+{
+       gpointer process_handle;
+       gpointer thread_handle;
+       guint32 pid; /* Contains GetLastError () on failure */
+       guint32 tid;
+       MonoArray *env_keys;
+       MonoArray *env_values;
+       MonoString *username;
+       MonoString *domain;
+       gpointer password; /* BSTR from SecureString in 2.0 profile */
+       MonoBoolean load_user_profile;
+} MonoW32ProcessInfo;
+
+typedef struct
+{
+       MonoObject object;
+       MonoString *filename;
+       MonoString *arguments;
+       MonoString *working_directory;
+       MonoString *verb;
+       guint32 window_style;
+       MonoBoolean error_dialog;
+       gpointer error_dialog_parent_handle;
+       MonoBoolean use_shell_execute;
+       MonoString *username;
+       MonoString *domain;
+       MonoObject *password; /* SecureString in 2.0 profile, dummy in 1.x */
+       MonoString *password_in_clear_text;
+       MonoBoolean load_user_profile;
+       MonoBoolean redirect_standard_input;
+       MonoBoolean redirect_standard_output;
+       MonoBoolean redirect_standard_error;
+       MonoObject *encoding_stdout;
+       MonoObject *encoding_stderr;
+       MonoBoolean create_no_window;
+       MonoObject *weak_parent_process;
+       MonoObject *envVars;
+} MonoW32ProcessStartInfo;
+
+void
+mono_w32process_init (void);
+
+void
+mono_w32process_cleanup (void);
+
+#ifndef HOST_WIN32
+
+void
+mono_w32process_set_cli_launcher (gchar *path);
+
+gchar*
+mono_w32process_get_path (pid_t pid);
+
+#endif
+
+gpointer
+ves_icall_System_Diagnostics_Process_GetProcess_internal (guint32 pid);
+
+MonoArray*
+ves_icall_System_Diagnostics_Process_GetProcesses_internal (void);
+
+MonoArray*
+ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObject *this_obj, gpointer process);
+
+void
+ves_icall_System_Diagnostics_FileVersionInfo_GetVersionInfo_internal (MonoObject *this_obj, MonoString *filename);
+
+MonoBoolean
+ves_icall_System_Diagnostics_Process_ShellExecuteEx_internal (MonoW32ProcessStartInfo *proc_start_info, MonoW32ProcessInfo *process_handle);
+
+MonoBoolean
+ves_icall_System_Diagnostics_Process_CreateProcess_internal (MonoW32ProcessStartInfo *proc_start_info, gpointer stdin_handle,
+       gpointer stdout_handle, gpointer stderr_handle, MonoW32ProcessInfo *process_handle);
+
+MonoString*
+ves_icall_System_Diagnostics_Process_ProcessName_internal (gpointer process);
+
+gint64
+ves_icall_System_Diagnostics_Process_GetProcessData (int pid, gint32 data_type, gint32 *error);
+
+gpointer
+ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcess (void);
+
+MonoBoolean
+ves_icall_Microsoft_Win32_NativeMethods_GetExitCodeProcess (gpointer handle, gint32 *exitcode);
+
+MonoBoolean
+ves_icall_Microsoft_Win32_NativeMethods_CloseProcess (gpointer handle);
+
+MonoBoolean
+ves_icall_Microsoft_Win32_NativeMethods_TerminateProcess (gpointer handle, gint32 exitcode);
+
+MonoBoolean
+ves_icall_Microsoft_Win32_NativeMethods_GetProcessWorkingSetSize (gpointer handle, gsize *min, gsize *max);
+MonoBoolean
+ves_icall_Microsoft_Win32_NativeMethods_SetProcessWorkingSetSize (gpointer handle, gsize min, gsize max);
+
+gint32
+ves_icall_Microsoft_Win32_NativeMethods_GetPriorityClass (gpointer handle);
+MonoBoolean
+ves_icall_Microsoft_Win32_NativeMethods_SetPriorityClass (gpointer handle, gint32 priorityClass);
+
+MonoBoolean
+ves_icall_Microsoft_Win32_NativeMethods_GetProcessTimes (gpointer handle, gint64 *creationtime, gint64 *exittime, gint64 *kerneltime, gint64 *usertime);
+
+G_END_DECLS
+
+#endif /* _MONO_METADATA_W32PROCESS_H_ */
+
index 21e7921127aae4b0c69731225cecaeef9d58e4f8..3e87ad8ad3f086fe415ebf26d34aac1bec0a78e1 100644 (file)
@@ -12,7 +12,7 @@
 #include "w32handle-namespace.h"
 #include "mono/io-layer/io-layer.h"
 #include "mono/utils/mono-logger-internals.h"
-#include "mono/utils/w32handle.h"
+#include "mono/metadata/w32handle.h"
 
 typedef struct {
        guint32 val;
index 57835f473e99bd8bc58fd389046140d2bad1e775..ce15318d225a66a654d0dc3fb2226743bfe236ea 100644 (file)
@@ -1432,7 +1432,6 @@ arch_emit_got_access (MonoAotCompile *acfg, const char *got_symbol, guint8 *code
 #elif defined(TARGET_POWERPC)
        {
                guint8 buf [32];
-               guint8 *code;
 
                emit_bytes (acfg, code, mono_arch_get_patch_offset (code));
                code = buf;
@@ -2491,7 +2490,7 @@ mono_get_field_token (MonoClassField *field)
 
        for (i = 0; i < klass->field.count; ++i) {
                if (field == &klass->fields [i])
-                       return MONO_TOKEN_FIELD_DEF | (klass->field.first + 1 + i);
+                       return MONO_TOKEN_FIELD_DEF | (mono_class_get_first_field_idx (klass) + 1 + i);
        }
 
        g_assert_not_reached ();
@@ -2770,7 +2769,7 @@ encode_klass_ref_inner (MonoAotCompile *acfg, MonoClass *klass, guint8 *buf, gui
         * information.
         */
 
-       if (klass->generic_class) {
+       if (mono_class_is_ginst (klass)) {
                guint32 token;
                g_assert (klass->type_token);
 
@@ -2780,8 +2779,8 @@ encode_klass_ref_inner (MonoAotCompile *acfg, MonoClass *klass, guint8 *buf, gui
                        encode_value (MONO_AOT_TYPEREF_TYPESPEC_TOKEN, p, &p);
                        encode_value (token, p, &p);
                } else {
-                       MonoClass *gclass = klass->generic_class->container_class;
-                       MonoGenericInst *inst = klass->generic_class->context.class_inst;
+                       MonoClass *gclass = mono_class_get_generic_class (klass)->container_class;
+                       MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
                        static int count = 0;
                        guint8 *p1 = p;
 
@@ -2855,7 +2854,7 @@ encode_klass_ref (MonoAotCompile *acfg, MonoClass *klass, guint8 *buf, guint8 **
        /* 
         * The encoding of generic instances is large so emit them only once.
         */
-       if (klass->generic_class) {
+       if (mono_class_is_ginst (klass)) {
                guint32 token;
                g_assert (klass->type_token);
 
@@ -3616,7 +3615,7 @@ can_marshal_struct (MonoClass *klass)
        MonoMarshalType *info;
        int i;
 
-       if ((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT)
+       if (mono_class_is_auto_layout (klass))
                return FALSE;
 
        info = mono_marshal_load_type_info (klass);
@@ -3688,8 +3687,8 @@ create_gsharedvt_inst (MonoAotCompile *acfg, MonoMethod *method, MonoGenericCont
 
        memset (ctx, 0, sizeof (MonoGenericContext));
 
-       if (method->klass->generic_container) {
-               shared_context = method->klass->generic_container->context;
+       if (mono_class_is_gtd (method->klass)) {
+               shared_context = mono_class_get_generic_container (method->klass)->context;
                inst = shared_context.class_inst;
 
                args = g_new0 (MonoType*, inst->type_argc);
@@ -3968,7 +3967,7 @@ add_wrappers (MonoAotCompile *acfg)
                if (!klass->delegate || klass == mono_defaults.delegate_class || klass == mono_defaults.multicastdelegate_class)
                        continue;
 
-               if (!klass->generic_container) {
+               if (!mono_class_is_gtd (klass)) {
                        method = mono_get_delegate_invoke (klass);
 
                        m = mono_marshal_get_delegate_invoke (method, NULL);
@@ -4008,7 +4007,7 @@ add_wrappers (MonoAotCompile *acfg)
                                        add_method (acfg, del_invoke);
                                }
                        }
-               } else if ((acfg->opts & MONO_OPT_GSHAREDVT) && klass->generic_container) {
+               } else if ((acfg->opts & MONO_OPT_GSHAREDVT) && mono_class_is_gtd (klass)) {
                        MonoError error;
                        MonoGenericContext ctx;
                        MonoMethod *inst, *gshared;
@@ -4102,7 +4101,7 @@ add_wrappers (MonoAotCompile *acfg)
                if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED) {
                        if (method->is_generic) {
                                // FIXME:
-                       } else if ((acfg->opts & MONO_OPT_GSHAREDVT) && method->klass->generic_container) {
+                       } else if ((acfg->opts & MONO_OPT_GSHAREDVT) && mono_class_is_gtd (method->klass)) {
                                MonoError error;
                                MonoGenericContext ctx;
                                MonoMethod *inst, *gshared, *m;
@@ -4276,7 +4275,7 @@ add_wrappers (MonoAotCompile *acfg)
                        continue;
                }
 
-               if (klass->valuetype && !klass->generic_container && can_marshal_struct (klass) &&
+               if (klass->valuetype && !mono_class_is_gtd (klass) && can_marshal_struct (klass) &&
                        !(klass->nested_in && strstr (klass->nested_in->name, "<PrivateImplementationDetails>") == klass->nested_in->name)) {
                        add_method (acfg, mono_marshal_get_struct_to_ptr (klass));
                        add_method (acfg, mono_marshal_get_ptr_to_struct (klass));
@@ -4291,8 +4290,8 @@ has_type_vars (MonoClass *klass)
                return TRUE;
        if (klass->rank)
                return has_type_vars (klass->element_class);
-       if (klass->generic_class) {
-               MonoGenericContext *context = &klass->generic_class->context;
+       if (mono_class_is_ginst (klass)) {
+               MonoGenericContext *context = &mono_class_get_generic_class (klass)->context;
                if (context->class_inst) {
                        int i;
 
@@ -4301,7 +4300,7 @@ has_type_vars (MonoClass *klass)
                                        return TRUE;
                }
        }
-       if (klass->generic_container)
+       if (mono_class_is_gtd (klass))
                return TRUE;
        return FALSE;
 }
@@ -4411,13 +4410,13 @@ add_generic_class_with_depth (MonoAotCompile *acfg, MonoClass *klass, int depth,
 
        mono_class_init (klass);
 
-       if (klass->generic_class && klass->generic_class->context.class_inst->is_open)
+       if (mono_class_is_ginst (klass) && mono_class_get_generic_class (klass)->context.class_inst->is_open)
                return;
 
        if (has_type_vars (klass))
                return;
 
-       if (!klass->generic_class && !klass->rank)
+       if (!mono_class_is_ginst (klass) && !klass->rank)
                return;
 
        if (mono_class_has_failure (klass))
@@ -4441,7 +4440,7 @@ add_generic_class_with_depth (MonoAotCompile *acfg, MonoClass *klass, int depth,
         * Use gsharedvt for generic collections with vtype arguments to avoid code blowup.
         * Enable this only for some classes since gsharedvt might not support all methods.
         */
-       if ((acfg->opts & MONO_OPT_GSHAREDVT) && klass->image == mono_defaults.corlib && klass->generic_class && klass->generic_class->context.class_inst && is_vt_inst (klass->generic_class->context.class_inst) &&
+       if ((acfg->opts & MONO_OPT_GSHAREDVT) && klass->image == mono_defaults.corlib && mono_class_is_ginst (klass) && mono_class_get_generic_class (klass)->context.class_inst && is_vt_inst (mono_class_get_generic_class (klass)->context.class_inst) &&
                (!strcmp (klass->name, "Dictionary`2") || !strcmp (klass->name, "List`1") || !strcmp (klass->name, "ReadOnlyCollection`1")))
                use_gsharedvt = TRUE;
 
@@ -4498,7 +4497,7 @@ add_generic_class_with_depth (MonoAotCompile *acfg, MonoClass *klass, int depth,
         */
        if (klass->image == mono_defaults.corlib && !strcmp (klass->name_space, "System.Collections.Generic") &&
                (!strcmp(klass->name, "ICollection`1") || !strcmp (klass->name, "IEnumerable`1") || !strcmp (klass->name, "IList`1") || !strcmp (klass->name, "IEnumerator`1") || !strcmp (klass->name, "IReadOnlyList`1"))) {
-               MonoClass *tclass = mono_class_from_mono_type (klass->generic_class->context.class_inst->type_argv [0]);
+               MonoClass *tclass = mono_class_from_mono_type (mono_class_get_generic_class (klass)->context.class_inst->type_argv [0]);
                MonoClass *array_class = mono_bounded_array_class_get (tclass, 1, FALSE);
                gpointer iter;
                char *name_prefix;
@@ -4519,7 +4518,7 @@ add_generic_class_with_depth (MonoAotCompile *acfg, MonoClass *klass, int depth,
                                        break;
                        }
                        g_assert (nclass);
-                       nclass = mono_class_inflate_generic_class_checked (nclass, mono_generic_class_get_context (klass->generic_class), &error);
+                       nclass = mono_class_inflate_generic_class_checked (nclass, mono_generic_class_get_context (mono_class_get_generic_class (klass)), &error);
                        mono_error_assert_ok (&error); /* FIXME don't swallow the error */
                        add_generic_class (acfg, nclass, FALSE, "ICollection<T>");
                }
@@ -4539,7 +4538,7 @@ add_generic_class_with_depth (MonoAotCompile *acfg, MonoClass *klass, int depth,
        /* Add an instance of GenericComparer<T> which is created dynamically by Comparer<T> */
        if (klass->image == mono_defaults.corlib && !strcmp (klass->name_space, "System.Collections.Generic") && !strcmp (klass->name, "Comparer`1")) {
                MonoError error;
-               MonoClass *tclass = mono_class_from_mono_type (klass->generic_class->context.class_inst->type_argv [0]);
+               MonoClass *tclass = mono_class_from_mono_type (mono_class_get_generic_class (klass)->context.class_inst->type_argv [0]);
                MonoClass *icomparable, *gcomparer, *icomparable_inst;
                MonoGenericContext ctx;
                MonoType *args [16];
@@ -4567,7 +4566,7 @@ add_generic_class_with_depth (MonoAotCompile *acfg, MonoClass *klass, int depth,
        /* Add an instance of GenericEqualityComparer<T> which is created dynamically by EqualityComparer<T> */
        if (klass->image == mono_defaults.corlib && !strcmp (klass->name_space, "System.Collections.Generic") && !strcmp (klass->name, "EqualityComparer`1")) {
                MonoError error;
-               MonoClass *tclass = mono_class_from_mono_type (klass->generic_class->context.class_inst->type_argv [0]);
+               MonoClass *tclass = mono_class_from_mono_type (mono_class_get_generic_class (klass)->context.class_inst->type_argv [0]);
                MonoClass *iface, *gcomparer, *iface_inst;
                MonoGenericContext ctx;
                MonoType *args [16];
@@ -4596,7 +4595,7 @@ add_generic_class_with_depth (MonoAotCompile *acfg, MonoClass *klass, int depth,
        /* Add an instance of EnumComparer<T> which is created dynamically by EqualityComparer<T> for enums */
        if (klass->image == mono_defaults.corlib && !strcmp (klass->name_space, "System.Collections.Generic") && !strcmp (klass->name, "EqualityComparer`1")) {
                MonoClass *enum_comparer;
-               MonoClass *tclass = mono_class_from_mono_type (klass->generic_class->context.class_inst->type_argv [0]);
+               MonoClass *tclass = mono_class_from_mono_type (mono_class_get_generic_class (klass)->context.class_inst->type_argv [0]);
                MonoGenericContext ctx;
                MonoType *args [16];
 
@@ -4618,7 +4617,7 @@ add_generic_class_with_depth (MonoAotCompile *acfg, MonoClass *klass, int depth,
        /* Add an instance of ObjectComparer<T> which is created dynamically by Comparer<T> for enums */
        if (klass->image == mono_defaults.corlib && !strcmp (klass->name_space, "System.Collections.Generic") && !strcmp (klass->name, "Comparer`1")) {
                MonoClass *comparer;
-               MonoClass *tclass = mono_class_from_mono_type (klass->generic_class->context.class_inst->type_argv [0]);
+               MonoClass *tclass = mono_class_from_mono_type (mono_class_get_generic_class (klass)->context.class_inst->type_argv [0]);
                MonoGenericContext ctx;
                MonoType *args [16];
 
@@ -4794,7 +4793,7 @@ add_generic_instances (MonoAotCompile *acfg)
                                g_free (type_argv);
                        }
 
-                       if (method->is_generic || method->klass->generic_container)
+                       if (method->is_generic || mono_class_is_gtd (method->klass))
                                declaring_method = method;
                        else
                                declaring_method = mono_method_get_declaring_generic_method (method);
@@ -5013,7 +5012,7 @@ is_direct_callable (MonoAotCompile *acfg, MonoMethod *method, MonoJumpInfo *patc
                if (callee_cfg) {
                        gboolean direct_callable = TRUE;
 
-                       if (direct_callable && !(!callee_cfg->has_got_slots && (callee_cfg->method->klass->flags & TYPE_ATTRIBUTE_BEFORE_FIELD_INIT)))
+                       if (direct_callable && !(!callee_cfg->has_got_slots && mono_class_is_before_field_init (callee_cfg->method->klass)))
                                direct_callable = FALSE;
                        if ((callee_cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED) && (!method || method->wrapper_type != MONO_WRAPPER_SYNCHRONIZED))
                                // FIXME: Maybe call the wrapper directly ?
@@ -5809,6 +5808,7 @@ encode_patch (MonoAotCompile *acfg, MonoJumpInfo *patch_info, guint8 *buf, guint
                encode_method_ref (acfg, patch_info->data.virt_method->method, p, &p);
                break;
        case MONO_PATCH_INFO_GC_SAFE_POINT_FLAG:
+       case MONO_PATCH_INFO_GET_TLS_TRAMP:
                break;
        default:
                g_warning ("unable to handle jump info %d", patch_info->type);
@@ -6272,11 +6272,11 @@ emit_klass_info (MonoAotCompile *acfg, guint32 token)
 
        mono_class_has_finalizer (klass);
 
-       if (klass->generic_container || cant_encode) {
+       if (mono_class_is_gtd (klass) || cant_encode) {
                encode_value (-1, p, &p);
        } else {
                encode_value (klass->vtable_size, p, &p);
-               encode_value ((klass->generic_container ? (1 << 8) : 0) | (no_special_static << 7) | (klass->has_static_refs << 6) | (klass->has_references << 5) | ((klass->blittable << 4) | ((klass->ext && klass->ext->nested_classes) ? 1 : 0) << 3) | (klass->has_cctor << 2) | (klass->has_finalize << 1) | klass->ghcimpl, p, &p);
+               encode_value ((mono_class_is_gtd (klass) ? (1 << 8) : 0) | (no_special_static << 7) | (klass->has_static_refs << 6) | (klass->has_references << 5) | ((klass->blittable << 4) | ((klass->ext && klass->ext->nested_classes) ? 1 : 0) << 3) | (klass->has_cctor << 2) | (klass->has_finalize << 1) | klass->ghcimpl, p, &p);
                if (klass->has_cctor)
                        encode_method_ref (acfg, mono_class_get_cctor (klass), p, &p);
                if (klass->has_finalize)
@@ -7329,7 +7329,7 @@ is_concrete_type (MonoType *t)
                if (!MONO_TYPE_ISSTRUCT (t))
                        return TRUE;
                klass = mono_class_from_mono_type (t);
-               orig_ctx = &klass->generic_class->context;
+               orig_ctx = &mono_class_get_generic_class (klass)->context;
 
                inst = orig_ctx->class_inst;
                if (inst) {
@@ -7466,7 +7466,7 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method)
        InterlockedIncrement (&acfg->stats.mcount);
 
 #if 0
-       if (method->is_generic || method->klass->generic_container) {
+       if (method->is_generic || mono_class_is_gtd (method->klass)) {
                InterlockedIncrement (&acfg->stats.genericcount);
                return;
        }
@@ -7645,7 +7645,7 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method)
                        case MONO_PATCH_INFO_VTABLE: {
                                MonoClass *klass = patch_info->data.klass;
 
-                               if (klass->generic_class && !mini_class_is_generic_sharable (klass))
+                               if (mono_class_is_ginst (klass) && !mini_class_is_generic_sharable (klass))
                                        add_generic_class_with_depth (acfg, klass, depth + 5, "vtable");
                                break;
                        }
@@ -7653,7 +7653,7 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method)
                                MonoClass *klass = patch_info->data.field->parent;
 
                                /* The .cctor needs to run at runtime. */
-                               if (klass->generic_class && !mono_generic_context_is_sharable_full (&klass->generic_class->context, FALSE, FALSE) && mono_class_get_cctor (klass))
+                               if (mono_class_is_ginst (klass) && !mono_generic_context_is_sharable_full (&mono_class_get_generic_class (klass)->context, FALSE, FALSE) && mono_class_get_cctor (klass))
                                        add_extra_method_with_depth (acfg, mono_class_get_cctor (klass), depth + 1);
                                break;
                        }
@@ -8192,7 +8192,7 @@ mono_aot_patch_info_dup (MonoJumpInfo* ji)
 static int
 execute_system (const char * command)
 {
-       int status;
+       int status = 0;
 
 #if _WIN32
        // We need an extra set of quotes around the whole command to properly handle commands 
@@ -8630,8 +8630,8 @@ mono_aot_method_hash (MonoMethod *method)
 
        sig = mono_method_signature (method);
 
-       if (method->klass->generic_class)
-               class_ginst = method->klass->generic_class->context.class_inst;
+       if (mono_class_is_ginst (method->klass))
+               class_ginst = mono_class_get_generic_class (method->klass)->context.class_inst;
        if (method->is_inflated)
                ginst = ((MonoMethodInflated*)method)->context.method_inst;
 
@@ -8648,8 +8648,8 @@ mono_aot_method_hash (MonoMethod *method)
        if (!method->wrapper_type) {
                char *full_name;
 
-               if (klass->generic_class)
-                       full_name = mono_type_full_name (&klass->generic_class->container_class->byval_arg);
+               if (mono_class_is_ginst (klass))
+                       full_name = mono_type_full_name (&mono_class_get_generic_class (klass)->container_class->byval_arg);
                else
                        full_name = mono_type_full_name (&klass->byval_arg);
 
@@ -9746,7 +9746,7 @@ collect_methods (MonoAotCompile *acfg)
                }
                */
 
-               if (method->is_generic || method->klass->generic_container)
+               if (method->is_generic || mono_class_is_gtd (method->klass))
                        /* Compile the ref shared version instead */
                        method = mini_get_shared_method (method);
 
@@ -9767,7 +9767,7 @@ collect_methods (MonoAotCompile *acfg)
                method = mono_get_method_checked (acfg->image, token, NULL, NULL, &error);
                report_loader_error (acfg, &error, "Failed to load method token 0x%x due to %s\n", i, mono_error_get_message (&error));
 
-               if (method->is_generic || method->klass->generic_container) {
+               if (method->is_generic || mono_class_is_gtd (method->klass)) {
                        MonoMethod *gshared;
 
                        gshared = mini_get_shared_method_full (method, TRUE, TRUE);
@@ -9791,7 +9791,7 @@ compile_methods (MonoAotCompile *acfg)
                GPtrArray *frag;
                int len, j;
                GPtrArray *threads;
-               HANDLE handle;
+               MonoThreadHandle *thread_handle;
                gpointer *user_data;
                MonoMethod **methods;
 
@@ -9824,13 +9824,13 @@ compile_methods (MonoAotCompile *acfg)
                        user_data [1] = acfg;
                        user_data [2] = frag;
                        
-                       handle = mono_threads_create_thread (compile_thread_main, (gpointer) user_data, NULL, NULL);
-                       g_ptr_array_add (threads, handle);
+                       thread_handle = mono_threads_create_thread (compile_thread_main, (gpointer) user_data, NULL, NULL);
+                       g_ptr_array_add (threads, thread_handle);
                }
                g_free (methods);
 
                for (i = 0; i < threads->len; ++i) {
-                       WaitForSingleObjectEx (g_ptr_array_index (threads, i), INFINITE, FALSE);
+                       mono_thread_info_wait_one_handle (g_ptr_array_index (threads, i), INFINITE, FALSE);
                        mono_threads_close_thread_handle (g_ptr_array_index (threads, i));
                }
        } else {
@@ -10382,6 +10382,11 @@ add_preinit_got_slots (MonoAotCompile *acfg)
        get_got_offset (acfg, FALSE, ji);
        get_got_offset (acfg, TRUE, ji);
 
+       ji = (MonoJumpInfo *)mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJumpInfo));
+       ji->type = MONO_PATCH_INFO_GET_TLS_TRAMP;
+       get_got_offset (acfg, FALSE, ji);
+       get_got_offset (acfg, TRUE, ji);
+
        for (i = 0; i < sizeof (preinited_jit_icalls) / sizeof (char*); ++i) {
                ji = (MonoJumpInfo *)mono_mempool_alloc0 (acfg->mempool, sizeof (MonoAotCompile));
                ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
@@ -10647,7 +10652,7 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options)
                        acfg->tmpfname = g_strdup_printf ("%s", acfg->aot_opts.outfile);
                else
                        acfg->tmpfname = g_strdup_printf ("%s.s", acfg->image->name);
-                       acfg->fp = fopen (acfg->tmpfname, "w+");
+               acfg->fp = fopen (acfg->tmpfname, "w+");
        } else {
                int i = g_file_open_tmp ("mono_aot_XXXXXX", &acfg->tmpfname, NULL);
                acfg->fp = fdopen (i, "w+");
index 0da4ad6168d75584271a6ed781aac682d494c79d..c531afce043a4dc4ed03e3dd3909e7585c437a78 100644 (file)
@@ -473,7 +473,7 @@ decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError
                gclass = decode_klass_ref (module, p, &p, error);
                if (!gclass)
                        return NULL;
-               g_assert (gclass->generic_container);
+               g_assert (mono_class_is_gtd (gclass));
 
                memset (&ctx, 0, sizeof (ctx));
                ctx.class_inst = decode_generic_inst (module, p, &p, error);
@@ -528,7 +528,7 @@ decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError
                                        if (!class_def)
                                                return NULL;
 
-                                       container = class_def->generic_container;
+                                       container = mono_class_try_get_generic_container (class_def); //FIXME is this a case for a try_get?
                                }
                        } else {
                                // We didn't decode is_method, so we have to infer it from type enum.
@@ -684,7 +684,7 @@ decode_type (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError *err
                gclass = decode_klass_ref (module, p, &p, error);
                if (!gclass)
                        goto fail;
-               g_assert (gclass->generic_container);
+               g_assert (mono_class_is_gtd (gclass));
 
                memset (&ctx, 0, sizeof (ctx));
                ctx.class_inst = decode_generic_inst (module, p, &p, error);
@@ -694,7 +694,7 @@ decode_type (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError *err
                if (!type)
                        goto fail;
                klass = mono_class_from_mono_type (type);
-               t->data.generic_class = klass->generic_class;
+               t->data.generic_class = mono_class_get_generic_class (klass);
                break;
        }
        case MONO_TYPE_ARRAY: {
@@ -1259,8 +1259,8 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
 
                memset (&ctx, 0, sizeof (ctx));
 
-               if (FALSE && klass->generic_class) {
-                       ctx.class_inst = klass->generic_class->context.class_inst;
+               if (FALSE && mono_class_is_ginst (klass)) {
+                       ctx.class_inst = mono_class_get_generic_class (klass)->context.class_inst;
                        ctx.method_inst = NULL;
  
                        ref->method = mono_class_inflate_generic_method_full_checked (ref->method, klass, &ctx, error);
@@ -2444,7 +2444,7 @@ mono_aot_get_cached_class_info (MonoClass *klass, MonoCachedClassInfo *res)
        guint8 *p;
        gboolean err;
 
-       if (klass->rank || !amodule)
+       if (klass->rank || !klass->type_token || !amodule)
                return FALSE;
 
        p = (guint8*)&amodule->blob [mono_aot_get_offset (amodule->class_info_offsets, mono_metadata_token_index (klass->type_token) - 1)];
@@ -3702,6 +3702,7 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
                break;
        }
        case MONO_PATCH_INFO_GC_SAFE_POINT_FLAG:
+       case MONO_PATCH_INFO_GET_TLS_TRAMP:
                break;
        case MONO_PATCH_INFO_AOT_JIT_INFO:
                ji->data.index = decode_value (p, &p);
@@ -4212,7 +4213,7 @@ init_method (MonoAotModule *amodule, guint32 method_index, MonoMethod *method, M
        gboolean inited_ok = TRUE;
        if (init_class)
                inited_ok = mono_runtime_class_init_full (mono_class_vtable (domain, init_class), error);
-       else if (from_plt && klass_to_run_ctor && !klass_to_run_ctor->generic_container)
+       else if (from_plt && klass_to_run_ctor && !mono_class_is_gtd (klass_to_run_ctor))
                inited_ok = mono_runtime_class_init_full (mono_class_vtable (domain, klass_to_run_ctor), error);
        if (!inited_ok)
                return FALSE;
@@ -4279,10 +4280,10 @@ mono_aot_init_gshared_method_mrgctx (gpointer aot_module, guint32 method_index,
        MonoGenericContext context = { NULL, NULL };
        MonoClass *klass = rgctx->class_vtable->klass;
 
-       if (klass->generic_class)
-               context.class_inst = klass->generic_class->context.class_inst;
-       else if (klass->generic_container)
-               context.class_inst = klass->generic_container->context.class_inst;
+       if (mono_class_is_ginst (klass))
+               context.class_inst = mono_class_get_generic_class (klass)->context.class_inst;
+       else if (mono_class_is_gtd (klass))
+               context.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
        context.method_inst = rgctx->method_inst;
 
        init_llvmonly_method (amodule, method_index, NULL, rgctx->class_vtable->klass, &context);
index cab90f84d3de89b717e58beaf13e98419f440afa..c85bd5e0f1dd6558cabbeb11e7e483d968ebcf01 100644 (file)
@@ -8,10 +8,11 @@
  * Copyright 2011 Xamarin Inc.  http://www.xamarin.com
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
- #include "mini.h"
 
+#include "config.h"
 #ifndef DISABLE_JIT
+
+#include "mini.h"
 
 /*
  * Returns true if @bb is a basic block which falls through the next block.
index 8ba135ce1321da6d05b39b6e080ac940c4c03162..ec40de9a8bc83cb65a81e1d54d372fc64adda781 100644 (file)
@@ -669,7 +669,7 @@ static MonoGHashTable *tid_to_thread_obj;
 
 static MonoNativeThreadId debugger_thread_id;
 
-static HANDLE debugger_thread_handle;
+static MonoThreadHandle *debugger_thread_handle;
 
 static int log_level;
 
@@ -6683,7 +6683,7 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8
 
        if (!m->klass->valuetype && !(m->flags & METHOD_ATTRIBUTE_STATIC) && !this_arg) {
                if (!strcmp (m->name, ".ctor")) {
-                       if (m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT)
+                       if (mono_class_is_abstract (m->klass))
                                return ERR_INVALID_ARGUMENT;
                        else {
                                MonoError error;
@@ -8036,7 +8036,7 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint
                        buffer_add_id (buf, 0);
                buffer_add_int (buf, klass->type_token);
                buffer_add_byte (buf, klass->rank);
-               buffer_add_int (buf, klass->flags);
+               buffer_add_int (buf, mono_class_get_flags (klass));
                b = 0;
                type = &klass->byval_arg;
                // FIXME: Can't decide whenever a class represents a byref type
@@ -8050,9 +8050,9 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint
                        b |= (1 << 3);
                if (klass->enumtype)
                        b |= (1 << 4);
-               if (klass->generic_container)
+               if (mono_class_is_gtd (klass))
                        b |= (1 << 5);
-               if (klass->generic_container || klass->generic_class)
+               if (mono_class_is_gtd (klass) || mono_class_is_ginst (klass))
                        b |= (1 << 6);
                buffer_add_byte (buf, b);
                nnested = 0;
@@ -8064,25 +8064,25 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint
                while ((nested = mono_class_get_nested_types (klass, &iter)))
                        buffer_add_typeid (buf, domain, nested);
                if (CHECK_PROTOCOL_VERSION (2, 12)) {
-                       if (klass->generic_container)
+                       if (mono_class_is_gtd (klass))
                                buffer_add_typeid (buf, domain, klass);
-                       else if (klass->generic_class)
-                               buffer_add_typeid (buf, domain, klass->generic_class->container_class);
+                       else if (mono_class_is_ginst (klass))
+                               buffer_add_typeid (buf, domain, mono_class_get_generic_class (klass)->container_class);
                        else
                                buffer_add_id (buf, 0);
                }
                if (CHECK_PROTOCOL_VERSION (2, 15)) {
                        int count, i;
 
-                       if (klass->generic_class) {
-                               MonoGenericInst *inst = klass->generic_class->context.class_inst;
+                       if (mono_class_is_ginst (klass)) {
+                               MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
 
                                count = inst->type_argc;
                                buffer_add_int (buf, count);
                                for (i = 0; i < count; i++)
                                        buffer_add_typeid (buf, domain, mono_class_from_mono_type (inst->type_argv [i]));
-                       } else if (klass->generic_container) {
-                               MonoGenericContainer *container = klass->generic_container;
+                       } else if (mono_class_is_gtd (klass)) {
+                               MonoGenericContainer *container = mono_class_get_generic_container (klass);
                                MonoClass *pklass;
 
                                count = container->type_argc;
@@ -8911,7 +8911,7 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g
                }
                ginst = mono_metadata_get_generic_inst (type_argc, type_argv);
                g_free (type_argv);
-               tmp_context.class_inst = method->klass->generic_class ? method->klass->generic_class->context.class_inst : NULL;
+               tmp_context.class_inst = mono_class_is_ginst (method->klass) ? mono_class_get_generic_class (method->klass)->context.class_inst : NULL;
                tmp_context.method_inst = ginst;
 
                inflated = mono_class_inflate_generic_method_checked (method, &tmp_context, &error);
index 14c97cbae30775317768cd2e19df55635904dc95..7d0716dad90c909c3d68fd2f59b0f2af827ad276 100644 (file)
 #include <mono/metadata/gc-internals.h>
 #include <mono/metadata/coree.h>
 #include <mono/metadata/attach.h>
+#include <mono/metadata/w32process.h>
 #include "mono/utils/mono-counters.h"
 #include "mono/utils/mono-hwcap.h"
 #include "mono/utils/mono-logger-internals.h"
-#include "mono/utils/w32handle.h"
+#include "mono/metadata/w32handle.h"
 
 #include "mini.h"
 #include "jit.h"
@@ -934,7 +935,7 @@ compile_all_methods_thread_main_inner (CompileAllThreadArgs *args)
                    (method->flags & METHOD_ATTRIBUTE_ABSTRACT))
                        continue;
 
-               if (method->klass->generic_container)
+               if (mono_class_is_gtd (method->klass))
                        continue;
                sig = mono_method_signature (method);
                if (!sig) {
@@ -1956,9 +1957,9 @@ mono_main (int argc, char* argv[])
        {
                char *runtime_path;
 
-               runtime_path = wapi_process_get_path (getpid ());
+               runtime_path = mono_w32process_get_path (getpid ());
                if (runtime_path) {
-                       wapi_process_set_cli_launcher (runtime_path);
+                       mono_w32process_set_cli_launcher (runtime_path);
                        g_free (runtime_path);
                }
        }
index fe210faa3a22ce14883bcad17c657328cf8bd746..9b7f762e9914a1512cbe5e6eacfa7a374e2b7a90 100644 (file)
@@ -29,15 +29,21 @@ mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot)
        MonoJumpInfo *ji = NULL;
        GSList *unwind_ops = NULL;
        int i, ctx_reg, size;
+       guint8 *labels [16];
 
        size = 256;
        code = start = mono_global_codeman_reserve (size);
 
        arm_movx (code, ARMREG_IP0, ARMREG_R0);
        ctx_reg = ARMREG_IP0;
+
        /* Restore fregs */
+       arm_ldrx (code, ARMREG_IP1, ctx_reg, MONO_STRUCT_OFFSET (MonoContext, has_fregs));
+       labels [0] = code;
+       arm_cbzx (code, ARMREG_IP1, 0);
        for (i = 0; i < 32; ++i)
                arm_ldrfpx (code, i, ctx_reg, MONO_STRUCT_OFFSET (MonoContext, fregs) + (i * 8));
+       mono_arm_patch (labels [0], code, MONO_R_ARM64_CBZ);
        /* Restore gregs */
        // FIXME: Restore less registers
        // FIXME: fp should be restored later
@@ -69,9 +75,10 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot)
 {
        guint8 *code;
        guint8* start;
-       int size, offset, gregs_offset, fregs_offset, ctx_offset, num_fregs, frame_size;
+       int i, size, offset, gregs_offset, fregs_offset, ctx_offset, num_fregs, frame_size;
        MonoJumpInfo *ji = NULL;
        GSList *unwind_ops = NULL;
+       guint8 *labels [16];
 
        size = 512;
        start = code = mono_global_codeman_reserve (size);
@@ -105,10 +112,19 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot)
        arm_strx (code, ARMREG_R0, ARMREG_FP, ctx_offset);
        /* Save gregs */
        code = mono_arm_emit_store_regarray (code, MONO_ARCH_CALLEE_SAVED_REGS | (1 << ARMREG_FP), ARMREG_FP, gregs_offset);
-       /* No need to save/restore fregs, since we don't currently use them */
+       /* Save fregs */
+       for (i = 0; i < num_fregs; ++i)
+               arm_strfpx (code, ARMREG_D8 + i, ARMREG_FP, fregs_offset + (i * 8));
 
        /* Load regs from ctx */
        code = mono_arm_emit_load_regarray (code, MONO_ARCH_CALLEE_SAVED_REGS, ARMREG_R0, MONO_STRUCT_OFFSET (MonoContext, regs));
+       /* Load fregs */
+       arm_ldrx (code, ARMREG_IP0, ARMREG_R0, MONO_STRUCT_OFFSET (MonoContext, has_fregs));
+       labels [0] = code;
+       arm_cbzx (code, ARMREG_IP0, 0);
+       for (i = 0; i < num_fregs; ++i)
+               arm_ldrfpx (code, ARMREG_D8 + i, ARMREG_R0, MONO_STRUCT_OFFSET (MonoContext, fregs) + (i * 8));
+       mono_arm_patch (labels [0], code, MONO_R_ARM64_CBZ);
        /* Load fp */
        arm_ldrx (code, ARMREG_FP, ARMREG_R0, MONO_STRUCT_OFFSET (MonoContext, regs) + (ARMREG_FP * 8));
 
@@ -126,6 +142,9 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot)
 
        /* Restore regs */
        code = mono_arm_emit_load_regarray (code, MONO_ARCH_CALLEE_SAVED_REGS, ARMREG_FP, gregs_offset);
+       /* Restore fregs */
+       for (i = 0; i < num_fregs; ++i)
+               arm_ldrfpx (code, ARMREG_D8 + i, ARMREG_FP, fregs_offset + (i * 8));
        /* Destroy frame */
        code = mono_arm_emit_destroy_frame (code, frame_size, (1 << ARMREG_IP0));
        arm_retx (code, ARMREG_LR);
@@ -374,6 +393,7 @@ mono_arm_throw_exception (gpointer arg, mgreg_t pc, mgreg_t *int_regs, gdouble *
        memset (&ctx, 0, sizeof (MonoContext));
        memcpy (&(ctx.regs [0]), int_regs, sizeof (mgreg_t) * 32);
        memcpy (&(ctx.fregs [ARMREG_D8]), fp_regs, sizeof (double) * 8);
+       ctx.has_fregs = 1;
        ctx.pc = pc;
 
        if (mono_object_isinst_checked (exc, mono_defaults.exception_class, &error)) {
@@ -402,6 +422,7 @@ mono_arm_resume_unwind (gpointer arg, mgreg_t pc, mgreg_t *int_regs, gdouble *fp
        memset (&ctx, 0, sizeof (MonoContext));
        memcpy (&(ctx.regs [0]), int_regs, sizeof (mgreg_t) * 32);
        memcpy (&(ctx.fregs [ARMREG_D8]), fp_regs, sizeof (double) * 8);
+       ctx.has_fregs = 1;
        ctx.pc = pc;
 
        mono_resume_unwind (&ctx);
index bb9c73c0400956edce182fcea82cc2887e726cd9..225b9f3b2364fb861618fb8f1b94a6f32a6ea0c8 100644 (file)
@@ -72,10 +72,10 @@ ldvirtfn_internal (MonoObject *obj, MonoMethod *method, gboolean gshared)
        if (gshared && method->is_inflated && mono_method_get_context (method)->method_inst) {
                MonoGenericContext context = { NULL, NULL };
 
-               if (res->klass->generic_class)
-                       context.class_inst = res->klass->generic_class->context.class_inst;
-               else if (res->klass->generic_container)
-                       context.class_inst = res->klass->generic_container->context.class_inst;
+               if (mono_class_is_ginst (res->klass))
+                       context.class_inst = mono_class_get_generic_class (res->klass)->context.class_inst;
+               else if (mono_class_is_gtd (res->klass))
+                       context.class_inst = mono_class_get_generic_container (res->klass)->context.class_inst;
                context.method_inst = mono_method_get_context (method)->method_inst;
 
                res = mono_class_inflate_generic_method_checked (res, &context, &error);
@@ -1108,8 +1108,8 @@ mono_helper_compile_generic_method (MonoObject *obj, MonoMethod *method, gpointe
                return NULL;
        }
        vmethod = mono_object_get_virtual_method (obj, method);
-       g_assert (!vmethod->klass->generic_container);
-       g_assert (!vmethod->klass->generic_class || !vmethod->klass->generic_class->context.class_inst->is_open);
+       g_assert (!mono_class_is_gtd (vmethod->klass));
+       g_assert (!mono_class_is_ginst (vmethod->klass) || !mono_class_get_generic_class (vmethod->klass)->context.class_inst->is_open);
        g_assert (!context->method_inst || !context->method_inst->is_open);
 
        addr = mono_compile_method_checked (vmethod, &error);
@@ -1334,7 +1334,7 @@ constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *k
 
        mono_error_init (error);
 
-       if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
+       if (mono_class_is_interface (klass)) {
                MonoObject *this_obj;
 
                /* Have to use the receiver's type instead of klass, the receiver is a ref type */
@@ -1352,7 +1352,7 @@ constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *k
                mono_class_setup_vtable (klass);
                g_assert (klass->vtable);
                vt_slot = mono_method_get_vtable_slot (cmethod);
-               if (cmethod->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
+               if (mono_class_is_interface (cmethod->klass)) {
                        iface_offset = mono_class_interface_offset (klass, cmethod->klass);
                        g_assert (iface_offset != -1);
                        vt_slot += iface_offset;
@@ -1608,10 +1608,10 @@ resolve_vcall (MonoVTable *vt, int slot, MonoMethod *imt_method, gpointer *out_a
                else
                        declaring = m;
 
-               if (m->klass->generic_class)
-                       context.class_inst = m->klass->generic_class->context.class_inst;
+               if (mono_class_is_ginst (m->klass))
+                       context.class_inst = mono_class_get_generic_class (m->klass)->context.class_inst;
                else
-                       g_assert (!m->klass->generic_container);
+                       g_assert (!mono_class_is_gtd (m->klass));
 
                generic_virtual = imt_method;
                g_assert (generic_virtual);
@@ -1692,10 +1692,10 @@ mono_resolve_generic_virtual_call (MonoVTable *vt, int slot, MonoMethod *generic
        else
                declaring = m;
 
-       if (m->klass->generic_class)
-               context.class_inst = m->klass->generic_class->context.class_inst;
+       if (mono_class_is_ginst (m->klass))
+               context.class_inst = mono_class_get_generic_class (m->klass)->context.class_inst;
        else
-               g_assert (!m->klass->generic_container);
+               g_assert (!mono_class_is_gtd (m->klass));
 
        g_assert (generic_virtual->is_inflated);
        context.method_inst = ((MonoMethodInflated*)generic_virtual)->context.method_inst;
index 8d73080631e424bf475d8bab179cde569b069fa9..77f8bc9578c9cea42168c5695dd3dca43d53ff6c 100644 (file)
@@ -151,7 +151,7 @@ bundle_save_library_initialize ()
        bundle_save_library_initialized = 1;
        char *path = g_build_filename (g_get_tmp_dir (), "mono-bundle-XXXXXX", NULL);
        bundled_dylibrary_directory = g_mkdtemp (path);
-       g_free (path);
+       /* don't free path - mkdtemp modifies it in place, and bundled_dylibrary_directory is an alias of it */
        if (bundled_dylibrary_directory == NULL)
                return;
        atexit (delete_bundled_libraries);
@@ -280,9 +280,10 @@ probe_embedded (const char *program, int *ref_argc, char **ref_argv [])
 
        mono_register_bundled_assemblies ((const MonoBundledAssembly **) assemblies->data);
        new_argv = g_new (char *, (*ref_argc)+1);
-       for (j = 0; j < *ref_argc; j++)
-               new_argv [j] = (*ref_argv)[j];
-       new_argv [j] = entry_point;
+       new_argv [0] = (*ref_argv)[0];
+       new_argv [1] = entry_point;
+       for (j = 1; j < *ref_argc; j++)
+               new_argv [j+1] = (*ref_argv)[j];
        *ref_argv = new_argv;
        (*ref_argc)++;
        
index 297516cb32c6290db4e4ded20a96f869000a95c3..3143431b6c48b11fab721ee8d1d0f6739519716b 100644 (file)
@@ -1657,7 +1657,7 @@ mini_emit_max_iid_check_vtable (MonoCompile *cfg, int vtable_reg, MonoClass *kla
 {
        int max_iid_reg = alloc_preg (cfg);
                
-       MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADU2_MEMBASE, max_iid_reg, vtable_reg, MONO_STRUCT_OFFSET (MonoVTable, max_interface_id));
+       MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADU4_MEMBASE, max_iid_reg, vtable_reg, MONO_STRUCT_OFFSET (MonoVTable, max_interface_id));
        mini_emit_max_iid_check (cfg, max_iid_reg, klass, false_target);
 }
 
@@ -1668,7 +1668,7 @@ mini_emit_max_iid_check_class (MonoCompile *cfg, int klass_reg, MonoClass *klass
 {
        int max_iid_reg = alloc_preg (cfg);
 
-       MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADU2_MEMBASE, max_iid_reg, klass_reg, MONO_STRUCT_OFFSET (MonoClass, max_interface_id));
+       MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADU4_MEMBASE, max_iid_reg, klass_reg, MONO_STRUCT_OFFSET (MonoClass, max_interface_id));
        mini_emit_max_iid_check (cfg, max_iid_reg, klass, false_target);
 }
 
@@ -1794,7 +1794,7 @@ mini_emit_castclass_inst (MonoCompile *cfg, int obj_reg, int klass_reg, MonoClas
                        mini_emit_class_check (cfg, eclass_reg, mono_defaults.enum_class);
                } else if (klass->cast_class == mono_defaults.enum_class) {
                        mini_emit_class_check (cfg, eclass_reg, mono_defaults.enum_class);
-               } else if (klass->cast_class->flags & TYPE_ATTRIBUTE_INTERFACE) {
+               } else if (mono_class_is_interface (klass->cast_class)) {
                        mini_emit_iface_class_cast (cfg, eclass_reg, klass->cast_class, NULL, NULL);
                } else {
                        // Pass -1 as obj_reg to skip the check below for arrays of arrays
@@ -2550,7 +2550,7 @@ check_method_sharing (MonoCompile *cfg, MonoMethod *cmethod, gboolean *out_pass_
        gboolean pass_mrgctx = FALSE;
 
        if (((cmethod->flags & METHOD_ATTRIBUTE_STATIC) || cmethod->klass->valuetype) &&
-               (cmethod->klass->generic_class || cmethod->klass->generic_container)) {
+               (mono_class_is_ginst (cmethod->klass) || mono_class_is_gtd (cmethod->klass))) {
                gboolean sharable = FALSE;
 
                if (mono_method_is_generic_sharable_full (cmethod, TRUE, TRUE, TRUE))
@@ -2791,7 +2791,7 @@ mono_emit_method_call_full (MonoCompile *cfg, MonoMethod *method, MonoMethodSign
        if (!sig)
                sig = mono_method_signature (method);
 
-       if (cfg->llvm_only && (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE))
+       if (cfg->llvm_only && (mono_class_is_interface (method->klass)))
                g_assert_not_reached ();
 
        if (rgctx_arg) {
@@ -2829,7 +2829,7 @@ mono_emit_method_call_full (MonoCompile *cfg, MonoMethod *method, MonoMethodSign
        if (cfg->llvm_only && !call_target && virtual_ && (method->flags & METHOD_ATTRIBUTE_VIRTUAL))
                return emit_llvmonly_virtual_call (cfg, method, sig, 0, args);
 
-       need_unbox_trampoline = method->klass == mono_defaults.object_class || (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE);
+       need_unbox_trampoline = method->klass == mono_defaults.object_class || mono_class_is_interface (method->klass);
 
        call = mono_emit_call_args (cfg, sig, args, FALSE, virtual_, tail, rgctx_arg ? TRUE : FALSE, need_unbox_trampoline);
 
@@ -2918,7 +2918,7 @@ mono_emit_method_call_full (MonoCompile *cfg, MonoMethod *method, MonoMethodSign
                } else {
                        vtable_reg = alloc_preg (cfg);
                        MONO_EMIT_NEW_LOAD_MEMBASE_FAULT (cfg, vtable_reg, this_reg, MONO_STRUCT_OFFSET (MonoObject, vtable));
-                       if (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
+                       if (mono_class_is_interface (method->klass)) {
                                guint32 imt_slot = mono_method_get_imt_slot (method);
                                emit_imt_argument (cfg, call, call->method, imt_arg);
                                slot_reg = vtable_reg;
@@ -4258,7 +4258,7 @@ handle_alloc (MonoCompile *cfg, MonoClass *klass, gboolean for_box, int context_
                EMIT_NEW_CLASSCONST (cfg, iargs [1], klass);
 
                alloc_ftn = ves_icall_object_new;
-       } else if (cfg->compile_aot && cfg->cbb->out_of_line && klass->type_token && klass->image == mono_defaults.corlib && !klass->generic_class) {
+       } else if (cfg->compile_aot && cfg->cbb->out_of_line && klass->type_token && klass->image == mono_defaults.corlib && !mono_class_is_ginst (klass)) {
                /* This happens often in argument checking code, eg. throw new FooException... */
                /* Avoid relocations and save some space by calling a helper function specialized to mscorlib */
                EMIT_NEW_ICONST (cfg, iargs [0], mono_metadata_token_index (klass->type_token));
@@ -4432,11 +4432,11 @@ mini_class_has_reference_variant_generic_argument (MonoCompile *cfg, MonoClass *
        MonoGenericContainer *container;
        MonoGenericInst *ginst;
 
-       if (klass->generic_class) {
-               container = klass->generic_class->container_class->generic_container;
-               ginst = klass->generic_class->context.class_inst;
-       } else if (klass->generic_container && context_used) {
-               container = klass->generic_container;
+       if (mono_class_is_ginst (klass)) {
+               container = mono_class_get_generic_container (mono_class_get_generic_class (klass)->container_class);
+               ginst = mono_class_get_generic_class (klass)->context.class_inst;
+       } else if (mono_class_is_gtd (klass) && context_used) {
+               container = mono_class_get_generic_container (klass);
                ginst = container->context.class_inst;
        } else {
                return FALSE;
@@ -4495,7 +4495,7 @@ method_needs_stack_walk (MonoCompile *cfg, MonoMethod *cmethod)
        return FALSE;
 }
 
-#define is_complex_isinst(klass) ((klass->flags & TYPE_ATTRIBUTE_INTERFACE) || klass->rank || mono_class_is_nullable (klass) || mono_class_is_marshalbyref (klass) || (klass->flags & TYPE_ATTRIBUTE_SEALED) || klass->byval_arg.type == MONO_TYPE_VAR || klass->byval_arg.type == MONO_TYPE_MVAR)
+#define is_complex_isinst(klass) (mono_class_is_interface (klass) || klass->rank || mono_class_is_nullable (klass) || mono_class_is_marshalbyref (klass) || mono_class_is_sealed (klass) || klass->byval_arg.type == MONO_TYPE_VAR || klass->byval_arg.type == MONO_TYPE_MVAR)
 
 static MonoInst*
 emit_isinst_with_cache (MonoCompile *cfg, MonoClass *klass, MonoInst **args)
@@ -4605,7 +4605,7 @@ handle_castclass (MonoCompile *cfg, MonoClass *klass, MonoInst *src, int context
 
        save_cast_details (cfg, klass, obj_reg, FALSE);
 
-       if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
+       if (mono_class_is_interface (klass)) {
                MONO_EMIT_NEW_LOAD_MEMBASE (cfg, vtable_reg, obj_reg, MONO_STRUCT_OFFSET (MonoObject, vtable));
                mini_emit_iface_cast (cfg, vtable_reg, klass, NULL, NULL);
        } else {
@@ -4613,7 +4613,7 @@ handle_castclass (MonoCompile *cfg, MonoClass *klass, MonoInst *src, int context
 
                MONO_EMIT_NEW_LOAD_MEMBASE (cfg, vtable_reg, obj_reg, MONO_STRUCT_OFFSET (MonoObject, vtable));
 
-               if (!klass->rank && !cfg->compile_aot && !(cfg->opt & MONO_OPT_SHARED) && (klass->flags & TYPE_ATTRIBUTE_SEALED)) {
+               if (!klass->rank && !cfg->compile_aot && !(cfg->opt & MONO_OPT_SHARED) && mono_class_is_sealed (klass)) {
                        /* the remoting code is broken, access the class for now */
                        if (0) { /*FIXME what exactly is broken? This change refers to r39380 from 2005 and mention some remoting fixes were due.*/
                                MonoVTable *vt = mono_class_vtable (cfg->domain, klass);
@@ -4686,7 +4686,7 @@ handle_isinst (MonoCompile *cfg, MonoClass *klass, MonoInst *src, int context_us
 
        MONO_EMIT_NEW_LOAD_MEMBASE (cfg, vtable_reg, obj_reg, MONO_STRUCT_OFFSET (MonoObject, vtable));
 
-       if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
+       if (mono_class_is_interface (klass)) {
                g_assert (!context_used);
                /* the is_null_bb target simply copies the input register to the output */
                mini_emit_iface_cast (cfg, vtable_reg, klass, false_bb, is_null_bb);
@@ -4716,7 +4716,7 @@ handle_isinst (MonoCompile *cfg, MonoClass *klass, MonoInst *src, int context_us
                        } else if (klass->cast_class == mono_defaults.enum_class) {
                                mini_emit_class_check_branch (cfg, eclass_reg, mono_defaults.enum_class, OP_PBEQ, is_null_bb);
                                MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_BR, false_bb);
-                       } else if (klass->cast_class->flags & TYPE_ATTRIBUTE_INTERFACE) {
+                       } else if (mono_class_is_interface (klass->cast_class)) {
                                mini_emit_iface_class_cast (cfg, eclass_reg, klass->cast_class, false_bb, is_null_bb);
                        } else {
                                if ((klass->rank == 1) && (klass->byval_arg.type == MONO_TYPE_SZARRAY)) {
@@ -4736,7 +4736,7 @@ handle_isinst (MonoCompile *cfg, MonoClass *klass, MonoInst *src, int context_us
                        /* the is_null_bb target simply copies the input register to the output */
                        mini_emit_isninst_cast (cfg, klass_reg, klass->cast_class, false_bb, is_null_bb);
                } else {
-                       if (!cfg->compile_aot && !(cfg->opt & MONO_OPT_SHARED) && (klass->flags & TYPE_ATTRIBUTE_SEALED)) {
+                       if (!cfg->compile_aot && !(cfg->opt & MONO_OPT_SHARED) && mono_class_is_sealed (klass)) {
                                g_assert (!context_used);
                                /* the remoting code is broken, access the class for now */
                                if (0) {/*FIXME what exactly is broken? This change refers to r39380 from 2005 and mention some remoting fixes were due.*/
@@ -4805,7 +4805,7 @@ handle_cisinst (MonoCompile *cfg, MonoClass *klass, MonoInst *src)
        MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, obj_reg, 0);
        MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_PBEQ, false_bb);
 
-       if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
+       if (mono_class_is_interface (klass)) {
 #ifndef DISABLE_REMOTING
                NEW_BBLOCK (cfg, interface_fail_bb);
 #endif
@@ -4909,7 +4909,7 @@ handle_ccastclass (MonoCompile *cfg, MonoClass *klass, MonoInst *src)
 
        save_cast_details (cfg, klass, obj_reg, FALSE);
 
-       if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
+       if (mono_class_is_interface (klass)) {
 #ifndef DISABLE_REMOTING
                NEW_BBLOCK (cfg, interface_fail_bb);
        
@@ -5186,7 +5186,7 @@ handle_constrained_gsharedvt_call (MonoCompile *cfg, MonoMethod *cmethod, MonoMe
         * This is hard to do with the current call code, since we would have to emit a branch and two different calls. So instead, we
         * pack the arguments into an array, and do the rest of the work in in an icall.
         */
-       if (((cmethod->klass == mono_defaults.object_class) || (cmethod->klass->flags & TYPE_ATTRIBUTE_INTERFACE) || (!cmethod->klass->valuetype && cmethod->klass->image != mono_defaults.corlib)) &&
+       if (((cmethod->klass == mono_defaults.object_class) || mono_class_is_interface (cmethod->klass) || (!cmethod->klass->valuetype && cmethod->klass->image != mono_defaults.corlib)) &&
                (MONO_TYPE_IS_VOID (fsig->ret) || MONO_TYPE_IS_PRIMITIVE (fsig->ret) || MONO_TYPE_IS_REFERENCE (fsig->ret) || MONO_TYPE_ISSTRUCT (fsig->ret) || mini_is_gsharedvt_type (fsig->ret)) &&
                (fsig->param_count == 0 || (!fsig->hasthis && fsig->param_count == 1) || (fsig->param_count == 1 && (MONO_TYPE_IS_REFERENCE (fsig->params [0]) || fsig->params [0]->byref || mini_is_gsharedvt_type (fsig->params [0]))))) {
                MonoInst *args [16];
@@ -5359,7 +5359,7 @@ mono_method_check_inlining (MonoCompile *cfg, MonoMethod *method)
                                        return FALSE;
                                }
                        }
-               } else if (method->klass->flags & TYPE_ATTRIBUTE_BEFORE_FIELD_INIT) {
+               } else if (mono_class_is_before_field_init (method->klass)) {
                        if (cfg->run_cctors && method->klass->has_cctor) {
                                /*FIXME it would easier and lazier to just use mono_class_try_get_vtable */
                                if (!method->klass->runtime_info)
@@ -5395,7 +5395,7 @@ mono_method_check_inlining (MonoCompile *cfg, MonoMethod *method)
                 * the cctor will need to be run at aot method load time, for example,
                 * or at the end of the compilation of the inlining method.
                 */
-               if (mono_class_needs_cctor_run (method->klass, NULL) && !((method->klass->flags & TYPE_ATTRIBUTE_BEFORE_FIELD_INIT)))
+               if (mono_class_needs_cctor_run (method->klass, NULL) && !mono_class_is_before_field_init (method->klass))
                        return FALSE;
        }
 
@@ -5425,7 +5425,7 @@ mini_field_access_needs_cctor_run (MonoCompile *cfg, MonoMethod *method, MonoCla
                        return FALSE;
        }
 
-       if (klass->flags & TYPE_ATTRIBUTE_BEFORE_FIELD_INIT) {
+       if (mono_class_is_before_field_init (klass)) {
                if (cfg->method == method)
                        return FALSE;
        }
@@ -7716,7 +7716,7 @@ emit_llvmonly_virtual_call (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSig
        MonoInst *icall_args [16];
        MonoInst *call_target, *ins, *vtable_ins;
        int arg_reg, this_reg, vtable_reg;
-       gboolean is_iface = cmethod->klass->flags & TYPE_ATTRIBUTE_INTERFACE;
+       gboolean is_iface = mono_class_is_interface (cmethod->klass);
        gboolean is_gsharedvt = cfg->gsharedvt && mini_is_gsharedvt_variable_signature (fsig);
        gboolean variant_iface = FALSE;
        guint32 slot;
@@ -7952,7 +7952,7 @@ is_jit_optimizer_disabled (MonoMethod *m)
                return FALSE;
        }
 
-       attrs = mono_custom_attrs_from_assembly_checked (ass, &error);
+       attrs = mono_custom_attrs_from_assembly_checked (ass, FALSE, &error);
        mono_error_cleanup (&error); /* FIXME don't swallow the error */
        if (attrs) {
                for (i = 0; i < attrs->num_attrs; ++i) {
@@ -9381,7 +9381,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 
                        n = fsig->param_count + fsig->hasthis;
 
-                       if (!cfg->gshared && cmethod->klass->generic_container)
+                       if (!cfg->gshared && mono_class_is_gtd (cmethod->klass))
                                UNVERIFIED;
 
                        if (!cfg->gshared)
@@ -9400,7 +9400,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                if (mini_is_gsharedvt_klass (constrained_class)) {
                                        if ((cmethod->klass != mono_defaults.object_class) && constrained_class->valuetype && cmethod->klass->valuetype) {
                                                /* The 'Own method' case below */
-                                       } else if (cmethod->klass->image != mono_defaults.corlib && !(cmethod->klass->flags & TYPE_ATTRIBUTE_INTERFACE) && !cmethod->klass->valuetype) {
+                                       } else if (cmethod->klass->image != mono_defaults.corlib && !mono_class_is_interface (cmethod->klass) && !cmethod->klass->valuetype) {
                                                /* 'The type parameter is instantiated as a reference type' case below. */
                                        } else {
                                                ins = handle_constrained_gsharedvt_call (cfg, cmethod, fsig, sp, constrained_class, &emit_widen);
@@ -9421,7 +9421,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                         * A simple solution would be to box always and make a normal virtual call, but that would
                                         * be bad performance wise.
                                         */
-                                       if (cmethod->klass->flags & TYPE_ATTRIBUTE_INTERFACE && cmethod->klass->generic_class) {
+                                       if (mono_class_is_interface (cmethod->klass) && mono_class_is_ginst (cmethod->klass)) {
                                                /*
                                                 * The parent classes implement no generic interfaces, so the called method will be a vtype method, so no boxing neccessary.
                                                 */
@@ -9474,7 +9474,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                                nonbox_call->dreg = ins->dreg;
                                                goto call_end;
                                        } else {
-                                               g_assert (cmethod->klass->flags & TYPE_ATTRIBUTE_INTERFACE);
+                                               g_assert (mono_class_is_interface (cmethod->klass));
                                                addr = emit_get_rgctx_virt_method (cfg, mono_class_check_context_used (constrained_class), constrained_class, cmethod, MONO_RGCTX_INFO_VIRT_METHOD_CODE);
                                                ins = (MonoInst*)mono_emit_calli (cfg, fsig, sp, addr, NULL, NULL);
                                                goto call_end;
@@ -9549,7 +9549,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                         * If the callee is a shared method, then its static cctor
                         * might not get called after the call was patched.
                         */
-                       if (cfg->gshared && cmethod->klass != method->klass && cmethod->klass->generic_class && mono_method_is_generic_sharable (cmethod, TRUE) && mono_class_needs_cctor_run (cmethod->klass, method)) {
+                       if (cfg->gshared && cmethod->klass != method->klass && mono_class_is_ginst (cmethod->klass) && mono_method_is_generic_sharable (cmethod, TRUE) && mono_class_needs_cctor_run (cmethod->klass, method)) {
                                emit_class_init (cfg, cmethod->klass);
                                CHECK_TYPELOAD (cmethod->klass);
                        }
@@ -9561,7 +9561,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 
                                context_used = mini_method_check_context_used (cfg, cmethod);
 
-                               if (context_used && (cmethod->klass->flags & TYPE_ATTRIBUTE_INTERFACE)) {
+                               if (context_used && mono_class_is_interface (cmethod->klass)) {
                                        /* Generic method interface
                                           calls are resolved via a
                                           helper function and don't
@@ -9804,13 +9804,13 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                         * This needs to be used for all generic calls, not just ones with a gsharedvt signature, to avoid
                         * patching gshared method addresses into a gsharedvt method.
                         */
-                       if (cfg->gsharedvt && (mini_is_gsharedvt_signature (fsig) || cmethod->is_inflated || cmethod->klass->generic_class) &&
+                       if (cfg->gsharedvt && (mini_is_gsharedvt_signature (fsig) || cmethod->is_inflated || mono_class_is_ginst (cmethod->klass)) &&
                                !(cmethod->klass->rank && cmethod->klass->byval_arg.type != MONO_TYPE_SZARRAY) &&
                                (!(cfg->llvm_only && virtual_ && (cmethod->flags & METHOD_ATTRIBUTE_VIRTUAL)))) {
                                MonoRgctxInfoType info_type;
 
                                if (virtual_) {
-                                       //if (cmethod->klass->flags & TYPE_ATTRIBUTE_INTERFACE)
+                                       //if (mono_class_is_interface (cmethod->klass))
                                                //GSHAREDVT_FAILURE (*ip);
                                        // disable for possible remoting calls
                                        if (fsig->hasthis && (mono_class_is_marshalbyref (method->klass) || method->klass == mono_defaults.object_class))
@@ -9823,7 +9823,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                                                                                                 cmethod, MONO_RGCTX_INFO_METHOD);
                                                /* This is not needed, as the trampoline code will pass one, and it might be passed in the same reg as the imt arg */
                                                vtable_arg = NULL;
-                                       } else if ((cmethod->klass->flags & TYPE_ATTRIBUTE_INTERFACE) && !imt_arg) {
+                                       } else if (mono_class_is_interface (cmethod->klass) && !imt_arg) {
                                                /* This can happen when we call a fully instantiated iface method */
                                                imt_arg = emit_get_rgctx_method (cfg, context_used,
                                                                                                                 cmethod, MONO_RGCTX_INFO_METHOD);
@@ -10858,7 +10858,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        if (mono_security_core_clr_enabled ())
                                ensure_method_is_allowed_to_call_method (cfg, method, cmethod);
 
-                       if (cfg->gshared && cmethod && cmethod->klass != method->klass && cmethod->klass->generic_class && mono_method_is_generic_sharable (cmethod, TRUE) && mono_class_needs_cctor_run (cmethod->klass, method)) {
+                       if (cfg->gshared && cmethod && cmethod->klass != method->klass && mono_class_is_ginst (cmethod->klass) && mono_method_is_generic_sharable (cmethod, TRUE) && mono_class_needs_cctor_run (cmethod->klass, method)) {
                                emit_class_init (cfg, cmethod->klass);
                                CHECK_TYPELOAD (cmethod->klass);
                        }
@@ -12175,7 +12175,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREP_MEMBASE_REG, addr->dreg, MONO_STRUCT_OFFSET (MonoTypedRef, klass), const_ins->dreg);
                                MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ADD_IMM, type_reg, const_ins->dreg, MONO_STRUCT_OFFSET (MonoClass, byval_arg));
                                MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREP_MEMBASE_REG, addr->dreg, MONO_STRUCT_OFFSET (MonoTypedRef, type), type_reg);
-                       } else if (cfg->compile_aot) {
+                       } else {
                                int const_reg = alloc_preg (cfg);
                                int type_reg = alloc_preg (cfg);
 
@@ -12183,9 +12183,6 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREP_MEMBASE_REG, addr->dreg, MONO_STRUCT_OFFSET (MonoTypedRef, klass), const_reg);
                                MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ADD_IMM, type_reg, const_reg, MONO_STRUCT_OFFSET (MonoClass, byval_arg));
                                MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREP_MEMBASE_REG, addr->dreg, MONO_STRUCT_OFFSET (MonoTypedRef, type), type_reg);
-                       } else {
-                               MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STOREP_MEMBASE_IMM, addr->dreg, MONO_STRUCT_OFFSET (MonoTypedRef, type), &klass->byval_arg);
-                               MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STOREP_MEMBASE_IMM, addr->dreg, MONO_STRUCT_OFFSET (MonoTypedRef, klass), klass);
                        }
                        MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREP_MEMBASE_REG, addr->dreg, MONO_STRUCT_OFFSET (MonoTypedRef, value), sp [0]->dreg);
 
@@ -15128,7 +15125,7 @@ mono_decompose_typecheck (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins)
                        ret = emit_isinst_with_cache_nonshared (cfg, source, klass);
                else
                        ret = emit_castclass_with_cache_nonshared (cfg, source, klass);
-       } else if (!context_used && (mono_class_is_marshalbyref (klass) || klass->flags & TYPE_ATTRIBUTE_INTERFACE)) {
+       } else if (!context_used && (mono_class_is_marshalbyref (klass) || mono_class_is_interface (klass))) {
                MonoInst *iargs [1];
                int costs;
 
index 82795e5b8e87e2e46c65bcc40e55190c19b4b338..13a3ffee37f8159a3b1346bf99c09b007ab5159b 100644 (file)
@@ -127,6 +127,7 @@ static int vfp_scratch2 = ARM_VFP_D1;
 static int i8_align;
 
 static gpointer single_step_tramp, breakpoint_tramp;
+static gpointer get_tls_tramp;
 
 /*
  * The code generated for sequence points reads from this location, which is
@@ -167,6 +168,9 @@ int mono_exc_esp_offset = 0;
 static void mono_arch_compute_omit_fp (MonoCompile *cfg);
 #endif
 
+static guint8*
+emit_aotconst (MonoCompile *cfg, guint8 *code, int dreg, int patch_type, gpointer data);
+
 const char*
 mono_arch_regname (int reg)
 {
@@ -330,9 +334,21 @@ mono_arm_emit_tls_get (MonoCompile *cfg, guint8* code, int dreg, int tls_offset)
 {
 #ifdef HAVE_FAST_TLS
        code = mono_arm_emit_load_imm (code, ARMREG_R0, tls_offset);
-       mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD,
-                       "mono_get_tls_key");
-       code = emit_call_seq (cfg, code);
+       if (cfg->compile_aot) {
+               /*
+                * This opcode is generated by CEE_MONO_JIT_ATTACH, so it can execute on
+                * threads which are not yet attached to the runtime. This means we can't
+                * call it directly, since the call would go through the trampoline code
+                * which assumes the thread is attached. So use a separate patch info type
+                * for it, and load it from a preinitialized GOT slot.
+                */
+               code = emit_aotconst (cfg, code, ARMREG_R1, MONO_PATCH_INFO_GET_TLS_TRAMP, NULL);
+               code = emit_call_reg (code, ARMREG_R1);
+       } else {
+               mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD,
+                                                        "mono_get_tls_key");
+               code = emit_call_seq (cfg, code);
+       }
        if (dreg != ARMREG_R0)
                ARM_MOV_REG_REG (code, dreg, ARMREG_R0);
 #else
@@ -347,9 +363,14 @@ mono_arm_emit_tls_get_reg (MonoCompile *cfg, guint8* code, int dreg, int tls_off
 #ifdef HAVE_FAST_TLS
        if (tls_offset_reg != ARMREG_R0)
                ARM_MOV_REG_REG (code, ARMREG_R0, tls_offset_reg);
-       mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD,
-                       "mono_get_tls_key");
-       code = emit_call_seq (cfg, code);
+       if (cfg->compile_aot) {
+               code = emit_aotconst (cfg, code, ARMREG_R1, MONO_PATCH_INFO_GET_TLS_TRAMP, NULL);
+               code = emit_call_reg (code, ARMREG_R1);
+       } else {
+               mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD,
+                                                        "mono_get_tls_key");
+               code = emit_call_seq (cfg, code);
+       }
        if (dreg != ARMREG_R0)
                ARM_MOV_REG_REG (code, dreg, ARMREG_R0);
 #else
@@ -5989,6 +6010,8 @@ mono_arch_register_lowlevel_calls (void)
                mono_register_jit_icall (tls_imp.get_tls_thunk, "mono_get_tls_key", mono_create_icall_signature ("ptr ptr"), TRUE);
                mono_register_jit_icall (tls_imp.set_tls_thunk, "mono_set_tls_key", mono_create_icall_signature ("void ptr ptr"), TRUE);
 
+               get_tls_tramp = tls_imp.get_tls_thunk;
+
                if (tls_imp.get_tls_thunk_end) {
                        mono_tramp_info_register (
                                mono_tramp_info_create (
@@ -7512,3 +7535,23 @@ mono_arch_get_call_info (MonoMemPool *mp, MonoMethodSignature *sig)
 {
        return get_call_info (mp, sig);
 }
+
+gpointer
+mono_arch_get_get_tls_tramp (void)
+{
+       return get_tls_tramp;
+}
+
+static guint8*
+emit_aotconst (MonoCompile *cfg, guint8 *code, int dreg, int patch_type, gpointer data)
+{
+       /* OP_AOTCONST */
+       mono_add_patch_info (cfg, code - cfg->native_code, patch_type, data);
+       ARM_LDR_IMM (code, dreg, ARMREG_PC, 0);
+       ARM_B (code, 0);
+       *(gpointer*)code = NULL;
+       code += 4;
+       /* Load the value from the GOT */
+       ARM_LDR_REG_REG (code, dreg, ARMREG_PC, dreg);
+       return code;
+}
index cb31a6e8b24f64f192e21cb32e1075805fbe0a8d..694f6b87e0e2d3f43ed800123f3925add53b1b2c 100644 (file)
@@ -350,6 +350,7 @@ typedef struct MonoCompileArch {
 #define MONO_ARCH_HAVE_SDB_TRAMPOLINES 1
 #define MONO_ARCH_HAVE_PATCH_CODE_NEW 1
 #define MONO_ARCH_HAVE_OP_GENERIC_CLASS_INIT 1
+#define MONO_ARCH_HAVE_GET_TLS_TRAMP 1
 
 #define MONO_ARCH_HAVE_TLS_GET (mono_arm_have_tls_get ())
 #define MONO_ARCH_HAVE_TLS_GET_REG 1
index 57a7a38deef9f7845a8aaf94024d58955698e06e..a8bf46b288661920056b90f3db2aa85be401c448 100644 (file)
@@ -4,6 +4,8 @@
  * (C) 2003 Ximian, Inc.
  */
 
+#include "config.h"
+
 #include <string.h>
 #include <math.h>
 #ifdef HAVE_UNISTD_H
@@ -21,6 +23,8 @@
 #include "trace.h"
 #include "mini-arch.h"
 
+#ifndef DISABLE_JIT
+
 #ifndef MONO_MAX_XREGS
 
 #define MONO_MAX_XREGS 0
@@ -28,7 +32,6 @@
 #define MONO_ARCH_CALLEE_XREGS 0
 
 #endif
 
 #define MONO_ARCH_BANK_MIRRORED -2
 
@@ -411,47 +414,7 @@ typedef struct {
        regmask_t preferred_mask; /* the hreg where the register should be allocated, or 0 */
 } RegTrack;
 
-#if !defined(DISABLE_LOGGING) && !defined(DISABLE_JIT)
-
-static const char* const patch_info_str[] = {
-#define PATCH_INFO(a,b) "" #a,
-#include "patch-info.h"
-#undef PATCH_INFO
-};
-
-const char*
-mono_ji_type_to_string (MonoJumpInfoType type)
-{
-       return patch_info_str [type];
-}
-
-void
-mono_print_ji (const MonoJumpInfo *ji)
-{
-       switch (ji->type) {
-       case MONO_PATCH_INFO_RGCTX_FETCH: {
-               MonoJumpInfoRgctxEntry *entry = ji->data.rgctx_entry;
-
-               printf ("[RGCTX_FETCH ");
-               mono_print_ji (entry->data);
-               printf (" - %s]", mono_rgctx_info_type_to_str (entry->info_type));
-               break;
-       }
-       case MONO_PATCH_INFO_METHODCONST: {
-               char *s = mono_method_full_name (ji->data.method, TRUE);
-               printf ("[METHODCONST - %s]", s);
-               g_free (s);
-               break;
-       }
-       case MONO_PATCH_INFO_INTERNAL_METHOD: {
-               printf ("[INTERNAL_METHOD - %s]", ji->data.name);
-               break;
-       }
-       default:
-               printf ("[%s]", patch_info_str [ji->type]);
-               break;
-       }
-}
+#if !defined(DISABLE_LOGGING)
 
 void
 mono_print_ins_index (int i, MonoInst *ins)
@@ -785,22 +748,11 @@ print_regtrack (RegTrack *t, int num)
 }
 #else
 
-const char*
-mono_ji_type_to_string (MonoJumpInfoType type)
-{
-       return "";
-}
-
-void
-mono_print_ji (const MonoJumpInfo *ji)
-{
-}
-
 void
 mono_print_ins_index (int i, MonoInst *ins)
 {
 }
-#endif /* !defined(DISABLE_LOGGING) && !defined(DISABLE_JIT) */
+#endif /* !defined(DISABLE_LOGGING) */
 
 void
 mono_print_ins (MonoInst *ins)
@@ -1151,8 +1103,6 @@ get_callee_mask (const char spec)
 static gint8 desc_to_fixed_reg [256];
 static gboolean desc_to_fixed_reg_inited = FALSE;
 
-#ifndef DISABLE_JIT
-
 /*
  * Local register allocation.
  * We first scan the list of instructions and we save the liveness info of
@@ -2554,47 +2504,6 @@ mono_opcode_to_type (int opcode, int cmp_opcode)
        }
 }
 
-#endif /* DISABLE_JIT */
-
-gboolean
-mono_is_regsize_var (MonoType *t)
-{
-       t = mini_get_underlying_type (t);
-       switch (t->type) {
-       case MONO_TYPE_I1:
-       case MONO_TYPE_U1:
-       case MONO_TYPE_I2:
-       case MONO_TYPE_U2:
-       case MONO_TYPE_I4:
-       case MONO_TYPE_U4:
-       case MONO_TYPE_I:
-       case MONO_TYPE_U:
-       case MONO_TYPE_PTR:
-       case MONO_TYPE_FNPTR:
-#if SIZEOF_REGISTER == 8
-       case MONO_TYPE_I8:
-       case MONO_TYPE_U8:
-#endif
-               return TRUE;
-       case MONO_TYPE_OBJECT:
-       case MONO_TYPE_STRING:
-       case MONO_TYPE_CLASS:
-       case MONO_TYPE_SZARRAY:
-       case MONO_TYPE_ARRAY:
-               return TRUE;
-       case MONO_TYPE_GENERICINST:
-               if (!mono_type_generic_inst_is_valuetype (t))
-                       return TRUE;
-               return FALSE;
-       case MONO_TYPE_VALUETYPE:
-               return FALSE;
-       default:
-               return FALSE;
-       }
-}
-
-#ifndef DISABLE_JIT
-
 /*
  * mono_peephole_ins:
  *
@@ -2844,3 +2753,40 @@ mono_regstate_free (MonoRegState *rs) {
 }
 
 #endif /* DISABLE_JIT */
+
+gboolean
+mono_is_regsize_var (MonoType *t)
+{
+       t = mini_get_underlying_type (t);
+       switch (t->type) {
+       case MONO_TYPE_I1:
+       case MONO_TYPE_U1:
+       case MONO_TYPE_I2:
+       case MONO_TYPE_U2:
+       case MONO_TYPE_I4:
+       case MONO_TYPE_U4:
+       case MONO_TYPE_I:
+       case MONO_TYPE_U:
+       case MONO_TYPE_PTR:
+       case MONO_TYPE_FNPTR:
+#if SIZEOF_REGISTER == 8
+       case MONO_TYPE_I8:
+       case MONO_TYPE_U8:
+#endif
+               return TRUE;
+       case MONO_TYPE_OBJECT:
+       case MONO_TYPE_STRING:
+       case MONO_TYPE_CLASS:
+       case MONO_TYPE_SZARRAY:
+       case MONO_TYPE_ARRAY:
+               return TRUE;
+       case MONO_TYPE_GENERICINST:
+               if (!mono_type_generic_inst_is_valuetype (t))
+                       return TRUE;
+               return FALSE;
+       case MONO_TYPE_VALUETYPE:
+               return FALSE;
+       default:
+               return FALSE;
+       }
+}
index a52f5eb80d06aef3137d018ac67b0940961f8460..4e632071ce2028c991303e2b827a93e61e2f0d8a 100644 (file)
@@ -166,8 +166,8 @@ gboolean
 mono_thread_state_init_from_handle (MonoThreadUnwindState *tctx, MonoThreadInfo *info)
 {
        kern_return_t ret;
-       mach_msg_type_number_t num_state;
-       thread_state_t state;
+       mach_msg_type_number_t num_state, num_fpstate;
+       thread_state_t state, fpstate;
        ucontext_t ctx;
        mcontext_t mctx;
        MonoJitTlsData *jit_tls;
@@ -183,15 +183,16 @@ mono_thread_state_init_from_handle (MonoThreadUnwindState *tctx, MonoThreadInfo
        tctx->unwind_data [MONO_UNWIND_DATA_JIT_TLS] = NULL;
 
        state = (thread_state_t) alloca (mono_mach_arch_get_thread_state_size ());
+       fpstate = (thread_state_t) alloca (mono_mach_arch_get_thread_fpstate_size ());
        mctx = (mcontext_t) alloca (mono_mach_arch_get_mcontext_size ());
 
        do {
-               ret = mono_mach_arch_get_thread_state (info->native_handle, state, &num_state);
+               ret = mono_mach_arch_get_thread_states (info->native_handle, state, &num_state, fpstate, &num_fpstate);
        } while (ret == KERN_ABORTED);
        if (ret != KERN_SUCCESS)
                return FALSE;
 
-       mono_mach_arch_thread_state_to_mcontext (state, mctx);
+       mono_mach_arch_thread_states_to_mcontext (state, fpstate, mctx);
        ctx.uc_mcontext = mctx;
 
        mono_sigctx_to_monoctx (&ctx, &tctx->ctx);
index 5342deb8b3a3027b899169417ae12da197786480..400940957fbd2e3c498784f371aaf5597e2de013 100644 (file)
@@ -613,23 +613,23 @@ get_generic_context_from_stack_frame (MonoJitInfo *ji, gpointer generic_info)
                klass = vtable->klass;
        }
 
-       //g_assert (!method->klass->generic_container);
-       if (method->klass->generic_class)
-               method_container_class = method->klass->generic_class->container_class;
+       //g_assert (!mono_class_is_gtd (method->klass));
+       if (mono_class_is_ginst (method->klass))
+               method_container_class = mono_class_get_generic_class (method->klass)->container_class;
        else
                method_container_class = method->klass;
 
        /* class might refer to a subclass of method's class */
-       while (!(klass == method->klass || (klass->generic_class && klass->generic_class->container_class == method_container_class))) {
+       while (!(klass == method->klass || (mono_class_is_ginst (klass) && mono_class_get_generic_class (klass)->container_class == method_container_class))) {
                klass = klass->parent;
                g_assert (klass);
        }
 
-       if (klass->generic_class || klass->generic_container)
+       if (mono_class_is_ginst (klass) || mono_class_is_gtd (klass))
                context.class_inst = mini_class_get_context (klass)->class_inst;
 
-       if (klass->generic_class)
-               g_assert (mono_class_has_parent_and_ignore_generics (klass->generic_class->container_class, method_container_class));
+       if (mono_class_is_ginst (klass))
+               g_assert (mono_class_has_parent_and_ignore_generics (mono_class_get_generic_class (klass)->container_class, method_container_class));
        else
                g_assert (mono_class_has_parent_and_ignore_generics (klass, method_container_class));
 
@@ -1229,7 +1229,7 @@ wrap_non_exception_throws (MonoMethod *m)
 
        klass = mono_class_get_runtime_compat_attr_class ();
 
-       attrs = mono_custom_attrs_from_assembly_checked (ass, &error);
+       attrs = mono_custom_attrs_from_assembly_checked (ass, FALSE, &error);
        mono_error_cleanup (&error); /* FIXME don't swallow the error */
        if (attrs) {
                for (i = 0; i < attrs->num_attrs; ++i) {
index da5b3afc6c259ae2bfe8eda0229cc37c75f91b01..07174330eb2ae3c8d85f8eb6122e605f6827a9fc 100644 (file)
@@ -76,7 +76,7 @@ type_check_context_used (MonoType *type, gboolean recursive)
                if (recursive) {
                        MonoGenericClass *gclass = type->data.generic_class;
 
-                       g_assert (gclass->container_class->generic_container);
+                       g_assert (mono_class_is_gtd (gclass->container_class));
                        return mono_generic_context_check_used (&gclass->context);
                } else {
                        return 0;
@@ -137,10 +137,10 @@ mono_class_check_context_used (MonoClass *klass)
        context_used |= type_check_context_used (&klass->this_arg, FALSE);
        context_used |= type_check_context_used (&klass->byval_arg, FALSE);
 
-       if (klass->generic_class)
-               context_used |= mono_generic_context_check_used (&klass->generic_class->context);
-       else if (klass->generic_container)
-               context_used |= mono_generic_context_check_used (&klass->generic_container->context);
+       if (mono_class_is_ginst (klass))
+               context_used |= mono_generic_context_check_used (&mono_class_get_generic_class (klass)->context);
+       else if (mono_class_is_gtd (klass))
+               context_used |= mono_generic_context_check_used (&mono_class_get_generic_container (klass)->context);
 
        return context_used;
 }
@@ -274,8 +274,8 @@ register_generic_subclass (MonoClass *klass)
 
        g_assert (rgctx_template);
 
-       if (parent->generic_class)
-               parent = parent->generic_class->container_class;
+       if (mono_class_is_ginst (parent))
+               parent = mono_class_get_generic_class (parent)->container_class;
 
        if (!generic_subclass_hash)
                generic_subclass_hash = g_hash_table_new (mono_aligned_addr_hash, NULL);
@@ -475,7 +475,7 @@ mono_class_get_method_generic (MonoClass *klass, MonoMethod *method)
                declaring = method;
 
        m = NULL;
-       if (klass->generic_class)
+       if (mono_class_is_ginst (klass))
                m = mono_class_get_inflated_method (klass, declaring);
 
        if (!m) {
@@ -734,8 +734,8 @@ class_get_rgctx_template_oti (MonoClass *klass, int type_argc, guint32 slot, gbo
 static MonoClass*
 class_uninstantiated (MonoClass *klass)
 {
-       if (klass->generic_class)
-               return klass->generic_class->container_class;
+       if (mono_class_is_ginst (klass))
+               return mono_class_get_generic_class (klass)->container_class;
        return klass;
 }
 
@@ -835,15 +835,15 @@ class_get_rgctx_template_oti (MonoClass *klass, int type_argc, guint32 slot, gbo
 
        DEBUG (printf ("get slot: %s %d\n", mono_type_full_name (&class->byval_arg), slot));
 
-       if (klass->generic_class && !shared) {
+       if (mono_class_is_ginst (klass) && !shared) {
                MonoRuntimeGenericContextInfoTemplate oti;
                gboolean tmp_do_free;
 
-               oti = class_get_rgctx_template_oti (klass->generic_class->container_class,
+               oti = class_get_rgctx_template_oti (mono_class_get_generic_class (klass)->container_class,
                                                                                        type_argc, slot, TRUE, FALSE, &tmp_do_free);
                if (oti.data) {
                        gpointer info = oti.data;
-                       oti.data = inflate_info (&oti, &klass->generic_class->context, klass, temporary);
+                       oti.data = inflate_info (&oti, &mono_class_get_generic_class (klass)->context, klass, temporary);
                        if (tmp_do_free)
                                free_inflated_info (oti.info_type, info);
                }
@@ -1118,7 +1118,7 @@ get_wrapper_shared_type (MonoType *t)
                        return get_wrapper_shared_type (&mono_defaults.object_class->byval_arg);
 
                klass = mono_class_from_mono_type (t);
-               orig_ctx = &klass->generic_class->context;
+               orig_ctx = &mono_class_get_generic_class (klass)->context;
 
                memset (&ctx, 0, sizeof (MonoGenericContext));
 
@@ -1136,7 +1136,7 @@ get_wrapper_shared_type (MonoType *t)
                                args [i] = get_wrapper_shared_type (inst->type_argv [i]);
                        ctx.method_inst = mono_metadata_get_generic_inst (inst->type_argc, args);
                }
-               klass = mono_class_inflate_generic_class_checked (klass->generic_class->container_class, &ctx, &error);
+               klass = mono_class_inflate_generic_class_checked (mono_class_get_generic_class (klass)->container_class, &ctx, &error);
                mono_error_assert_ok (&error); /* FIXME don't swallow the error */
                return &klass->byval_arg;
        }
@@ -1183,7 +1183,7 @@ mini_get_gsharedvt_in_sig_wrapper (MonoMethodSignature *sig)
        MonoMethod *res, *cached;
        WrapperInfo *info;
        MonoMethodSignature *csig, *gsharedvt_sig;
-       int i, pindex, retval_var;
+       int i, pindex, retval_var = 0;
        static GHashTable *cache;
 
        // FIXME: Memory management
@@ -1646,7 +1646,7 @@ instantiate_info (MonoDomain *domain, MonoRuntimeGenericContextInfoTemplate *oti
 
                mono_class_setup_vtable (info->klass);
                // FIXME: Check type load
-               if (iface_class->flags & TYPE_ATTRIBUTE_INTERFACE) {
+               if (mono_class_is_interface (iface_class)) {
                        ioffset = mono_class_interface_offset (info->klass, iface_class);
                        g_assert (ioffset != -1);
                } else {
@@ -1672,7 +1672,7 @@ instantiate_info (MonoDomain *domain, MonoRuntimeGenericContextInfoTemplate *oti
 
                mono_class_setup_vtable (info->klass);
                // FIXME: Check type load
-               if (iface_class->flags & TYPE_ATTRIBUTE_INTERFACE) {
+               if (mono_class_is_interface (iface_class)) {
                        ioffset = mono_class_interface_offset (info->klass, iface_class);
                        g_assert (ioffset != -1);
                } else {
@@ -1786,7 +1786,7 @@ instantiate_info (MonoDomain *domain, MonoRuntimeGenericContextInfoTemplate *oti
                                /* See mono_emit_method_call_full () */
                                /* The gsharedvt trampoline will recognize this constant */
                                vcall_offset = MONO_GSHAREDVT_DEL_INVOKE_VT_OFFSET;
-                       } else if (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
+                       } else if (mono_class_is_interface (method->klass)) {
                                guint32 imt_slot = mono_method_get_imt_slot (method);
                                vcall_offset = ((gint32)imt_slot - MONO_IMT_SIZE) * SIZEOF_VOID_P;
                        } else {
@@ -2058,8 +2058,8 @@ register_info (MonoClass *klass, int type_argc, gpointer data, MonoRgctxInfoType
                MonoRuntimeGenericContextTemplate *parent_template;
                MonoRuntimeGenericContextInfoTemplate *oti;
 
-               if (parent->generic_class)
-                       parent = parent->generic_class->container_class;
+               if (mono_class_is_ginst (parent))
+                       parent = mono_class_get_generic_class (parent)->container_class;
 
                parent_template = mono_class_get_runtime_generic_context_template (parent);
                oti = rgctx_template_get_other_slot (parent_template, type_argc, i);
@@ -2313,7 +2313,7 @@ fill_runtime_generic_context (MonoVTable *class_vtable, MonoRuntimeGenericContex
        int i, first_slot, size;
        MonoDomain *domain = class_vtable->domain;
        MonoClass *klass = class_vtable->klass;
-       MonoGenericContext *class_context = klass->generic_class ? &klass->generic_class->context : NULL;
+       MonoGenericContext *class_context = mono_class_is_ginst (klass) ? &mono_class_get_generic_class (klass)->context : NULL;
        MonoRuntimeGenericContextInfoTemplate oti;
        MonoGenericContext context = { class_context ? class_context->class_inst : NULL, method_inst };
        int rgctx_index;
@@ -2483,7 +2483,7 @@ mono_method_lookup_rgctx (MonoVTable *class_vtable, MonoGenericInst *method_inst
        MonoMethodRuntimeGenericContext *mrgctx;
        MonoMethodRuntimeGenericContext key;
 
-       g_assert (!class_vtable->klass->generic_container);
+       g_assert (!mono_class_is_gtd (class_vtable->klass));
        g_assert (!method_inst->is_open);
 
        mono_domain_lock (domain);
@@ -2634,7 +2634,7 @@ mono_method_is_generic_impl (MonoMethod *method)
           if not compiled with sharing. */
        if (method->wrapper_type != MONO_WRAPPER_NONE)
                return FALSE;
-       if (method->klass->generic_container)
+       if (mono_class_is_gtd (method->klass))
                return TRUE;
        return FALSE;
 }
@@ -2786,18 +2786,18 @@ mono_method_is_generic_sharable_full (MonoMethod *method, gboolean allow_type_va
                }
        }
 
-       if (method->klass->generic_class) {
-               if (!mono_generic_context_is_sharable_full (&method->klass->generic_class->context, allow_type_vars, allow_partial))
+       if (mono_class_is_ginst (method->klass)) {
+               if (!mono_generic_context_is_sharable_full (&mono_class_get_generic_class (method->klass)->context, allow_type_vars, allow_partial))
                        return FALSE;
 
-               g_assert (method->klass->generic_class->container_class &&
-                               method->klass->generic_class->container_class->generic_container);
+               g_assert (mono_class_get_generic_class (method->klass)->container_class &&
+                               mono_class_is_gtd (mono_class_get_generic_class (method->klass)->container_class));
 
-               if (has_constraints (method->klass->generic_class->container_class->generic_container))
+               if (has_constraints (mono_class_get_generic_container (mono_class_get_generic_class (method->klass)->container_class)))
                        return FALSE;
        }
 
-       if (method->klass->generic_container && !allow_type_vars)
+       if (mono_class_is_gtd (method->klass) && !allow_type_vars)
                return FALSE;
 
        /* This does potentially expensive cattr checks, so do it at the end */
@@ -2838,7 +2838,7 @@ mono_method_needs_static_rgctx_invoke (MonoMethod *method, gboolean allow_type_v
 
        return ((method->flags & METHOD_ATTRIBUTE_STATIC) ||
                        method->klass->valuetype) &&
-               (method->klass->generic_class || method->klass->generic_container);
+               (mono_class_is_ginst (method->klass) || mono_class_is_gtd (method->klass));
 }
 
 static MonoGenericInst*
@@ -2867,9 +2867,9 @@ mono_method_construct_object_context (MonoMethod *method)
 {
        MonoGenericContext object_context;
 
-       g_assert (!method->klass->generic_class);
-       if (method->klass->generic_container) {
-               int type_argc = method->klass->generic_container->type_argc;
+       g_assert (!mono_class_is_ginst (method->klass));
+       if (mono_class_is_gtd (method->klass)) {
+               int type_argc = mono_class_get_generic_container (method->klass)->type_argc;
 
                object_context.class_inst = get_object_generic_inst (type_argc);
        } else {
@@ -3003,10 +3003,10 @@ mono_generic_context_equal_deep (MonoGenericContext *context1, MonoGenericContex
 MonoClass*
 mini_class_get_container_class (MonoClass *klass)
 {
-       if (klass->generic_class)
-               return klass->generic_class->container_class;
+       if (mono_class_is_ginst (klass))
+               return mono_class_get_generic_class (klass)->container_class;
 
-       g_assert (klass->generic_container);
+       g_assert (mono_class_is_gtd (klass));
        return klass;
 }
 
@@ -3019,11 +3019,11 @@ mini_class_get_container_class (MonoClass *klass)
 MonoGenericContext*
 mini_class_get_context (MonoClass *klass)
 {
-       if (klass->generic_class)
-               return &klass->generic_class->context;
+       if (mono_class_is_ginst (klass))
+               return &mono_class_get_generic_class (klass)->context;
 
-       g_assert (klass->generic_container);
-       return &klass->generic_container->context;
+       g_assert (mono_class_is_gtd (klass));
+       return &mono_class_get_generic_container (klass)->context;
 }
 
 /*
@@ -3205,10 +3205,10 @@ mini_type_is_vtype (MonoType *t)
 gboolean
 mini_class_is_generic_sharable (MonoClass *klass)
 {
-       if (klass->generic_class && is_async_state_machine_class (klass))
+       if (mono_class_is_ginst (klass) && is_async_state_machine_class (klass))
                return FALSE;
 
-       return (klass->generic_class && mono_generic_context_is_sharable (&klass->generic_class->context, FALSE));
+       return (mono_class_is_ginst (klass) && mono_generic_context_is_sharable (&mono_class_get_generic_class (klass)->context, FALSE));
 }
 
 gboolean
@@ -3351,9 +3351,9 @@ get_shared_type (MonoType *t, MonoType *type)
 
                memset (&context, 0, sizeof (context));
                if (gclass->context.class_inst)
-                       context.class_inst = get_shared_inst (gclass->context.class_inst, gclass->container_class->generic_container->context.class_inst, NULL, FALSE, FALSE, TRUE);
+                       context.class_inst = get_shared_inst (gclass->context.class_inst, mono_class_get_generic_container (gclass->container_class)->context.class_inst, NULL, FALSE, FALSE, TRUE);
                if (gclass->context.method_inst)
-                       context.method_inst = get_shared_inst (gclass->context.method_inst, gclass->container_class->generic_container->context.method_inst, NULL, FALSE, FALSE, TRUE);
+                       context.method_inst = get_shared_inst (gclass->context.method_inst, mono_class_get_generic_container (gclass->container_class)->context.method_inst, NULL, FALSE, FALSE, TRUE);
 
                k = mono_class_inflate_generic_class_checked (gclass->container_class, &context, &error);
                mono_error_assert_ok (&error); /* FIXME don't swallow the error */
@@ -3456,7 +3456,7 @@ mini_get_shared_method_full (MonoMethod *method, gboolean all_vt, gboolean is_gs
                }
        }
 
-       if (method->is_generic || (method->klass->generic_container && !method->is_inflated)) {
+       if (method->is_generic || (mono_class_is_gtd (method->klass) && !method->is_inflated)) {
                declaring_method = method;
        } else {
                declaring_method = mono_method_get_declaring_generic_method (method);
@@ -3466,14 +3466,14 @@ mini_get_shared_method_full (MonoMethod *method, gboolean all_vt, gboolean is_gs
        if (declaring_method->is_generic)
                shared_context = mono_method_get_generic_container (declaring_method)->context;
        else
-               shared_context = declaring_method->klass->generic_container->context;
+               shared_context = mono_class_get_generic_container (declaring_method->klass)->context;
 
        if (!is_gsharedvt)
                partial = mono_method_is_generic_sharable_full (method, FALSE, TRUE, FALSE);
 
        gsharedvt = is_gsharedvt || (!partial && mini_is_gsharedvt_sharable_method (method));
 
-       class_container = declaring_method->klass->generic_container;
+       class_container = mono_class_try_get_generic_container (declaring_method->klass); //FIXME is this a case for a try_get?
        method_container = mono_method_get_generic_container (declaring_method);
 
        /*
index 1bf14393db25142339add6f35a4e311d3ccbc728..a93ee9d9111282efa41f7bbf365408f93ad5f96b 100644 (file)
@@ -233,7 +233,7 @@ void
 mono_llvm_set_call_notail (LLVMValueRef func)
 {
 #if LLVM_API_VERSION > 100
-       //unwrap<CallInst>(func)->setTailCallKind (CallInst::TailCallKind::TCK_NoTail);
+       unwrap<CallInst>(func)->setTailCallKind (CallInst::TailCallKind::TCK_NoTail);
 #endif
 }
 
index 3ccd8d705656f7b1b81c4719b117b4610c96d2df..98802978e85ef78a054087c0e0fe85fe7d106ce3 100644 (file)
@@ -6,7 +6,8 @@
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
-#include "mini.h"
+#include "config.h"
+
 #include <mono/metadata/debug-helpers.h>
 #include <mono/metadata/debug-mono-symfile.h>
 #include <mono/metadata/mempool-internals.h>
@@ -33,6 +34,8 @@
 #include "aot-compiler.h"
 #include "mini-llvm.h"
 
+#ifndef DISABLE_JIT
+
 #ifdef __MINGW32__
 
 #include <stddef.h>
@@ -3487,6 +3490,9 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
 
        lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
 
+       if (ins->opcode != OP_TAILCALL && LLVMGetInstructionOpcode (lcall) == LLVMCall)
+               mono_llvm_set_call_notail (lcall);
+
        /*
         * Modify cconv and parameter attributes to pass rgctx/imt correctly.
         */
@@ -9197,3 +9203,27 @@ default_mono_llvm_unhandled_exception (void)
  *   code.
  * - use pointer types to help optimizations.
  */
+
+#else /* DISABLE_JIT */
+
+void
+mono_llvm_cleanup (void)
+{
+}
+
+void
+mono_llvm_free_domain_info (MonoDomain *domain)
+{
+}
+
+void
+mono_llvm_init (void)
+{
+}
+
+void
+default_mono_llvm_unhandled_exception (void)
+{
+}
+
+#endif /* DISABLE_JIT */
index 92eb960a82278bc8c39c64cbb37d2cbeb5c5fb1f..572048ff5ff8b401b415ab6ba0fe9de8e88cc02f 100644 (file)
@@ -65,7 +65,7 @@
 #include <mono/utils/mono-threads.h>
 #include <mono/utils/mono-threads-coop.h>
 #include <mono/utils/checked-build.h>
-#include <mono/utils/w32handle.h>
+#include <mono/metadata/w32handle.h>
 #include <mono/io-layer/io-layer.h>
 
 #include "mini.h"
@@ -1094,6 +1094,63 @@ mono_patch_info_list_prepend (MonoJumpInfo *list, int ip, MonoJumpInfoType type,
        return ji;
 }
 
+#if !defined(DISABLE_LOGGING) && !defined(DISABLE_JIT)
+
+static const char* const patch_info_str[] = {
+#define PATCH_INFO(a,b) "" #a,
+#include "patch-info.h"
+#undef PATCH_INFO
+};
+
+const char*
+mono_ji_type_to_string (MonoJumpInfoType type)
+{
+       return patch_info_str [type];
+}
+
+void
+mono_print_ji (const MonoJumpInfo *ji)
+{
+       switch (ji->type) {
+       case MONO_PATCH_INFO_RGCTX_FETCH: {
+               MonoJumpInfoRgctxEntry *entry = ji->data.rgctx_entry;
+
+               printf ("[RGCTX_FETCH ");
+               mono_print_ji (entry->data);
+               printf (" - %s]", mono_rgctx_info_type_to_str (entry->info_type));
+               break;
+       }
+       case MONO_PATCH_INFO_METHODCONST: {
+               char *s = mono_method_full_name (ji->data.method, TRUE);
+               printf ("[METHODCONST - %s]", s);
+               g_free (s);
+               break;
+       }
+       case MONO_PATCH_INFO_INTERNAL_METHOD: {
+               printf ("[INTERNAL_METHOD - %s]", ji->data.name);
+               break;
+       }
+       default:
+               printf ("[%s]", patch_info_str [ji->type]);
+               break;
+       }
+}
+
+#else
+
+const char*
+mono_ji_type_to_string (MonoJumpInfoType type)
+{
+       return "";
+}
+
+void
+mono_print_ji (const MonoJumpInfo *ji)
+{
+}
+
+#endif
+
 /**
  * mono_patch_info_dup_mp:
  *
@@ -1222,6 +1279,7 @@ mono_patch_info_hash (gconstpointer data)
        case MONO_PATCH_INFO_GOT_OFFSET:
        case MONO_PATCH_INFO_GC_SAFE_POINT_FLAG:
        case MONO_PATCH_INFO_AOT_MODULE:
+       case MONO_PATCH_INFO_GET_TLS_TRAMP:
                return (ji->type << 8);
        case MONO_PATCH_INFO_CASTCLASS_CACHE:
                return (ji->type << 8) | (ji->data.index);
@@ -1441,11 +1499,11 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
                break;
        case MONO_PATCH_INFO_IID:
                mono_class_init (patch_info->data.klass);
-               target = GINT_TO_POINTER ((int)patch_info->data.klass->interface_id);
+               target = GUINT_TO_POINTER (patch_info->data.klass->interface_id);
                break;
        case MONO_PATCH_INFO_ADJUSTED_IID:
                mono_class_init (patch_info->data.klass);
-               target = GINT_TO_POINTER ((int)(-((patch_info->data.klass->interface_id + 1) * SIZEOF_VOID_P)));
+               target = GUINT_TO_POINTER ((guint32)(-((patch_info->data.klass->interface_id + 1) * SIZEOF_VOID_P)));
                break;
        case MONO_PATCH_INFO_VTABLE:
                target = mono_class_vtable (domain, patch_info->data.klass);
@@ -1475,7 +1533,7 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
                }
 
                g_assert (vtable);
-               if (!vtable->initialized && !(vtable->klass->flags & TYPE_ATTRIBUTE_BEFORE_FIELD_INIT) && (method && mono_class_needs_cctor_run (vtable->klass, method)))
+               if (!vtable->initialized && !mono_class_is_before_field_init (vtable->klass) && (method && mono_class_needs_cctor_run (vtable->klass, method)))
                        /* Done by the generated code */
                        ;
                else {
@@ -1661,6 +1719,13 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
        case MONO_PATCH_INFO_GSHAREDVT_IN_WRAPPER:
                target = mini_get_gsharedvt_wrapper (TRUE, NULL, patch_info->data.sig, NULL, -1, FALSE);
                break;
+       case MONO_PATCH_INFO_GET_TLS_TRAMP:
+#ifdef MONO_ARCH_HAVE_GET_TLS_TRAMP
+               target = mono_arch_get_get_tls_tramp ();
+#else
+               target = NULL;
+#endif
+               break;
        default:
                g_assert_not_reached ();
        }
@@ -1879,6 +1944,15 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoError *er
                if ((code = mono_aot_get_method_checked (domain, method, error))) {
                        MonoVTable *vtable;
 
+                       if (mono_runtime_is_critical_method (method) || mono_gc_is_critical_method (method)) {
+                               /*
+                                * The suspend code needs to be able to lookup these methods by ip in async context,
+                                * so preload their jit info.
+                                */
+                               MonoJitInfo *ji = mono_jit_info_table_find (domain, code);
+                               g_assert (ji);
+                       }
+
                        /*
                         * In llvm-only mode, method might be a shared method, so we can't initialize its class.
                         * This is not a problem, since it will be initialized when the method is first
@@ -3086,7 +3160,7 @@ mono_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *met
                return NULL;
 
        is_virtual_generic = method->is_inflated && mono_method_get_declaring_generic_method (method)->is_generic;
-       is_interface = method->klass->flags & TYPE_ATTRIBUTE_INTERFACE ? TRUE : FALSE;
+       is_interface = mono_class_is_interface (method->klass);
        load_imt_reg = is_virtual_generic || is_interface;
 
        if (is_interface)
@@ -4201,7 +4275,7 @@ mono_precompile_assembly (MonoAssembly *ass, void *user_data)
                }
                if (method->flags & METHOD_ATTRIBUTE_ABSTRACT)
                        continue;
-               if (method->is_generic || method->klass->generic_container)
+               if (method->is_generic || mono_class_is_gtd (method->klass))
                        continue;
 
                count++;
index 420a7b1a3bf6e0ce0c8dc951b45fa71049e34eb9..c3f763ac5d0670b23b3a9373ff2f428f730ece1a 100644 (file)
@@ -1292,6 +1292,7 @@ handle_enum:
 
        ip = ((gint64) __builtin_extract_return_addr (__builtin_return_address (0)));
        printf (" ip: %p\n", (gpointer) ip);
+       va_end (ap);
 }
 
 /*========================= End of Function ========================*/
index 122334e6ea6519613d4bd8e741fac583c13bafc7..7f37b4d8595122215981e9ac372ad48ab5b732fe 100644 (file)
@@ -198,8 +198,8 @@ mini_resolve_imt_method (MonoVTable *vt, gpointer *vtable_slot, MonoMethod *imt_
                /* imt_method->slot might not be set */
                impl = mono_class_get_vtable_entry (vt->klass, interface_offset + mono_method_get_declaring_generic_method (imt_method)->slot);
 
-               if (impl->klass->generic_class)
-                       context.class_inst = impl->klass->generic_class->context.class_inst;
+               if (mono_class_is_ginst (impl->klass))
+                       context.class_inst = mono_class_get_generic_class (impl->klass)->context.class_inst;
                context.method_inst = ((MonoMethodInflated*)imt_method)->context.method_inst;
                impl = mono_class_inflate_generic_method_checked (impl, &context, error);
                mono_error_assert_ok (error);
@@ -591,10 +591,10 @@ common_call_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVTable *
                else
                        declaring = m;
 
-               if (m->klass->generic_class)
-                       context.class_inst = m->klass->generic_class->context.class_inst;
+               if (mono_class_is_ginst (m->klass))
+                       context.class_inst = mono_class_get_generic_class (m->klass)->context.class_inst;
                else
-                       g_assert (!m->klass->generic_container);
+                       g_assert (!mono_class_is_gtd (m->klass));
 
                generic_virtual = mono_arch_find_imt_method (regs, code);
                g_assert (generic_virtual);
@@ -662,10 +662,10 @@ common_call_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVTable *
                        else
                                declaring = m;
 
-                       if (klass->generic_class)
-                               context.class_inst = klass->generic_class->context.class_inst;
-                       else if (klass->generic_container)
-                               context.class_inst = klass->generic_container->context.class_inst;
+                       if (mono_class_is_ginst (klass))
+                               context.class_inst = mono_class_get_generic_class (klass)->context.class_inst;
+                       else if (mono_class_is_gtd (klass))
+                               context.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
                        context.method_inst = method_inst;
 
                        actual_method = mono_class_inflate_generic_method_checked (declaring, &context, error);
@@ -850,7 +850,7 @@ mono_vcall_trampoline (mgreg_t *regs, guint8 *code, int slot, guint8 *tramp)
        gpointer *vtable_slot;
        MonoMethod *m;
        MonoError error;
-       gpointer addr, res;
+       gpointer addr, res = NULL;
 
        trampoline_calls ++;
 
@@ -935,10 +935,10 @@ mono_generic_virtual_remoting_trampoline (mgreg_t *regs, guint8 *code, MonoMetho
        else
                declaring = m;
 
-       if (m->klass->generic_class)
-               context.class_inst = m->klass->generic_class->context.class_inst;
+       if (mono_class_is_ginst (m->klass))
+               context.class_inst = mono_class_get_generic_class (m->klass)->context.class_inst;
        else
-               g_assert (!m->klass->generic_container);
+               g_assert (!mono_class_is_gtd (m->klass));
 
        imt_method = mono_arch_find_imt_method (regs, code);
        if (imt_method->is_inflated)
@@ -1188,7 +1188,7 @@ mono_delegate_trampoline (mgreg_t *regs, guint8 *code, gpointer *arg, guint8* tr
                         * If the call doesn't return a valuetype, then the vcall uses the same calling
                         * convention as a normal call.
                         */
-                       if (((method->klass->flags & TYPE_ATTRIBUTE_SEALED) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) && !MONO_TYPE_ISSTRUCT (sig->ret)) {
+                       if ((mono_class_is_sealed (method->klass) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) && !MONO_TYPE_ISSTRUCT (sig->ret)) {
                                callvirt = FALSE;
                                enable_caching = FALSE;
                        }
@@ -1197,7 +1197,7 @@ mono_delegate_trampoline (mgreg_t *regs, guint8 *code, gpointer *arg, guint8* tr
                if (delegate->target && 
                        method->flags & METHOD_ATTRIBUTE_VIRTUAL && 
                        method->flags & METHOD_ATTRIBUTE_ABSTRACT &&
-                       method->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) {
+                       mono_class_is_abstract (method->klass)) {
                        method = mono_object_get_virtual_method (delegate->target, method);
                        enable_caching = FALSE;
                }
index 815c59042ebf3562e7795da7b37ae341d97a207d..e94e9fc18c00e59ca5c5b38e0295d461819bbe4c 100644 (file)
@@ -2422,7 +2422,7 @@ mono_codegen (MonoCompile *cfg)
                gboolean is_generic = FALSE;
 
                if (cfg->method->is_inflated || mono_method_get_generic_container (cfg->method) ||
-                               cfg->method->klass->generic_container || cfg->method->klass->generic_class) {
+                               mono_class_is_gtd (cfg->method->klass) || mono_class_is_ginst (cfg->method->klass)) {
                        is_generic = TRUE;
                }
 
@@ -3335,7 +3335,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl
                cfg->seq_points = g_ptr_array_new ();
        mono_error_init (&cfg->error);
 
-       if (cfg->compile_aot && !try_generic_shared && (method->is_generic || method->klass->generic_container || method_is_gshared)) {
+       if (cfg->compile_aot && !try_generic_shared && (method->is_generic || mono_class_is_gtd (method->klass) || method_is_gshared)) {
                cfg->exception_type = MONO_EXCEPTION_GENERIC_SHARING_FAILED;
                return cfg;
        }
index 03ef9f89f199d3c3e606e3cf92af06d78fe8c600..1d4184ee09c37b27229fcf76bd41e634d3416a56 100644 (file)
@@ -509,7 +509,7 @@ enum {
 
 #define MONO_INS_IS_PCONST_NULL(ins) ((ins)->opcode == OP_PCONST && (ins)->inst_p0 == 0)
 
-#define MONO_METHOD_IS_FINAL(m) (((m)->flags & METHOD_ATTRIBUTE_FINAL) || ((m)->klass && ((m)->klass->flags & TYPE_ATTRIBUTE_SEALED)))
+#define MONO_METHOD_IS_FINAL(m) (((m)->flags & METHOD_ATTRIBUTE_FINAL) || ((m)->klass && (mono_class_get_flags ((m)->klass) & TYPE_ATTRIBUTE_SEALED)))
 
 
 #ifdef MONO_ARCH_SIMD_INTRINSICS
@@ -2679,6 +2679,7 @@ guint8*   mono_arch_create_sdb_trampoline (gboolean single_step, MonoTrampInfo *
 gpointer  mono_arch_create_monitor_enter_trampoline (MonoTrampInfo **info, gboolean is_v4, gboolean aot);
 gpointer  mono_arch_create_monitor_exit_trampoline (MonoTrampInfo **info, gboolean aot);
 guint8   *mono_arch_create_llvm_native_thunk     (MonoDomain *domain, guint8* addr) MONO_LLVM_INTERNAL;
+gpointer  mono_arch_get_get_tls_tramp (void);
 GList    *mono_arch_get_allocatable_int_vars    (MonoCompile *cfg);
 GList    *mono_arch_get_global_int_regs         (MonoCompile *cfg);
 GList    *mono_arch_get_global_fp_regs          (MonoCompile *cfg);
index e6635a4b49c8cfe2bf945c3efeb683bf9ea44a18..a55700355721adf50355dbc89013664042f1d700 100644 (file)
@@ -57,3 +57,4 @@ PATCH_INFO(AOT_JIT_INFO, "aot_jit_info")
 PATCH_INFO(GC_NURSERY_BITS, "gc_nursery_bits")
 PATCH_INFO(GSHAREDVT_IN_WRAPPER, "gsharedvt_in_wrapper")
 PATCH_INFO(ICALL_ADDR_CALL, "icall_addr_call")
+PATCH_INFO(GET_TLS_TRAMP, "get_tls_tramp")
index 98f89d63500b7fe89ea677a7bbe041a911dd4a00..90f0af81b5a2c2e606f9e4b2d7be094f7be8d357 100644 (file)
@@ -101,17 +101,21 @@ mono_trace_eval (MonoMethod *method)
                
                switch (op->op){
                case MONO_TRACEOP_ALL:
-                       inc = 1; break;
+                       inc = 1;
+                       break;
                case MONO_TRACEOP_PROGRAM:
                        if (trace_spec.assembly && (method->klass->image == mono_assembly_get_image (trace_spec.assembly)))
-                               inc = 1; break;
+                               inc = 1;
+                       break;
                case MONO_TRACEOP_WRAPPER:
                        if ((method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED) ||
                                (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE))
-                               inc = 1; break;
+                               inc = 1;
+                       break;
                case MONO_TRACEOP_METHOD:
                        if (mono_method_desc_full_match ((MonoMethodDesc *) op->data, method))
-                               inc = 1; break;
+                               inc = 1;
+                       break;
                case MONO_TRACEOP_CLASS:
                        if (strcmp (method->klass->name_space, op->data) == 0)
                                if (strcmp (method->klass->name, op->data2) == 0)
@@ -119,18 +123,21 @@ mono_trace_eval (MonoMethod *method)
                        break;
                case MONO_TRACEOP_ASSEMBLY:
                        if (strcmp (mono_image_get_name (method->klass->image), op->data) == 0)
-                               inc = 1; break;
+                               inc = 1;
+                       break;
                case MONO_TRACEOP_NAMESPACE:
                        if (strcmp (method->klass->name_space, op->data) == 0)
                                inc = 1;
+                       break;
                case MONO_TRACEOP_EXCEPTION:
                        break;
                }
-               if (op->exclude){
+               if (op->exclude) {
                        if (inc)
                                include = 0;
-               } else if (inc)
+               } else if (inc) {
                        include = 1;
+               }
        }
        return include;
 }
index 7d7cc41aa618c99bb060fd69eedcf9441ba4b559..03e2af6fd3943a8f6afcbb50c8c4994f98bde7f6 100644 (file)
@@ -881,7 +881,7 @@ mono_arch_get_plt_info_offset (guint8 *plt_entry, mgreg_t *regs, guint8 *code)
 guint8*
 mono_arch_create_sdb_trampoline (gboolean single_step, MonoTrampInfo **info, gboolean aot)
 {
-       int tramp_size = 256;
+       int tramp_size = 512;
        int i, framesize, ctx_offset, cfa_offset, gregs_offset;
        guint8 *code, *buf;
        GSList *unwind_ops = NULL;
index aefb07f23c5b6a99b9f3510a43d90c353f7a829d..e99244aecf1b2cbeb9a1e2a0d20e0c33046c2f03 100644 (file)
@@ -182,7 +182,7 @@ sgen_aligned_addr_hash (gconstpointer ptr)
        return GPOINTER_TO_UINT (ptr) >> 3;
 }
 
-#define SGEN_PTR_IN_NURSERY(p,bits,start,end)  (((mword)(p) & ~((1 << (bits)) - 1)) == (mword)(start))
+#define SGEN_PTR_IN_NURSERY(p,bits,start,end)  (((mword)(p) & ~(((mword)1 << (bits)) - 1)) == (mword)(start))
 
 #ifdef USER_CONFIG
 
index 511e581b66e8de2ea699639b8c4e1102b9835645..92276ab63b24fd4b96fd54bca9a14515e31ee814 100644 (file)
@@ -85,63 +85,64 @@ STRESS_TESTS_SRC=   \
        assembly-load-stress.cs
 
 BASE_TEST_MOBILE_STATIC_NOT_SUPPORTED= \
-       remoting4.cs            # Needs remoting support \
-       remoting1.cs            # Needs remoting support \
-       remoting2.cs            # Needs remoting support \
-       remoting3.cs            # Needs remoting support \
-       remoting5.cs            # Needs remoting support \
-       appdomain.cs        # Needs appdomain support \
-       appdomain-client.cs     # Needs appdomain support \
-       appdomain-unload.cs # Needs appdomain support \
-       appdomain-async-invoke.cs       # Needs appdomain support \
-       appdomain-thread-abort.cs       # Needs appdomain support \
-       appdomain1.cs           # Needs appdomain support \
-       appdomain2.cs           # Needs appdomain support \
-       appdomain-exit.cs       # Needs appdomain support \
-       assemblyresolve_event2.2.cs     # Needs appdomain support \
-       appdomain-unload-callback.cs    # Needs appdomain support \
-       appdomain-unload-doesnot-raise-pending-events.cs        # Needs appdomain support \
-       unload-appdomain-on-shutdown.cs # Needs appdomain support \
-       bug-47295.cs # Needs SRE \
-       loader.cs # Needs SRE \
-       pinvoke2.cs # Needs SRE \
-       generic-type-builder.2.cs       # Needs SRE \
-       dynamic-generic-size.cs # Needs SRE \
-       cominterop.cs   # Needs COM \
-       dynamic-method-access.2.cs      # Need SRE \
-       dynamic-method-finalize.2.cs    # Need SRE \
-       dynamic-method-stack-traces.cs # Need SRE\
-       generic_type_definition.2.cs    # Need SRE \
-       bug-333798-tb.2.cs      # Need SRE \
-       bug-335131.2.cs # Need SRE \
-       bug-322722_patch_bx.2.cs        # Need SRE\
-       bug-322722_dyn_method_throw.2.cs        # Need SRE \
-       bug-389886-2.cs # Need SRE \
-       bug-349190.2.cs # Need SRE \
-       bug-389886-sre-generic-interface-instances.cs   # Need SRE \
-       bug-462592.cs   # Need SRE \
-       bug-575941.cs   # Need SRE \
-       bug-389886-3.cs # Need SRE \
-       constant-division.cs    # Need SRE \
-       dynamic-method-resurrection.cs  # Need SRE \
-       bug-80307.cs    # Need System.Web \
-       assembly_append_ordering.cs # Need SRE \
-       bug-544446.cs   # Needs AppDomains / TranparentProxy \
-       bug-36848.cs   # Needs AppDomains / TranparentProxy \
-       generic-marshalbyref.2.cs # Needs AppDomains \
-       stackframes-async.2.cs # Needs AppDomains \
-       transparentproxy.cs # Needs AppDomains / TranparentProxy \
-       bug-48015.cs # Needs AppDomains / TranparentProxy \
-       delegate9.cs # Needs AppDomains \
-       marshal-valuetypes.cs   # Needs AppDomains \
-       xdomain-threads.cs      # Needs AppDomains \
-       monitor.cs # Needs AppDomains \
-       generic-xdomain.2.cs # Needs AppDomains \
-       threadpool-exceptions7.cs # Needs AppDomains \
-       cross-domain.cs # Needs AppDomains \
-       generic-unloading.2.cs # Needs AppDomains \
-       namedmutex-destroy-race.cs # needs named Mutex \
-       thread6.cs # On MOBILE, ThreadAbortException doesn't have necessary field for this test
+       remoting4.cs    \
+       remoting1.cs    \
+       remoting2.cs    \
+       remoting3.cs    \
+       remoting5.cs    \
+       appdomain.cs    \
+       appdomain-client.cs     \
+       appdomain-unload.cs     \
+       appdomain-async-invoke.cs       \
+       appdomain-thread-abort.cs       \
+       appdomain1.cs   \
+       appdomain2.cs   \
+       appdomain-exit.cs       \
+       assemblyresolve_event2.2.cs     \
+       appdomain-unload-callback.cs    \
+       appdomain-unload-doesnot-raise-pending-events.cs        \
+       unload-appdomain-on-shutdown.cs \
+       bug-47295.cs    \
+       loader.cs       \
+       pinvoke2.cs     \
+       generic-type-builder.2.cs       \
+       dynamic-generic-size.cs \
+       cominterop.cs   \
+       dynamic-method-access.2.cs      \
+       dynamic-method-finalize.2.cs    \
+       dynamic-method-stack-traces.cs  \
+       generic_type_definition.2.cs    \
+       bug-333798-tb.2.cs      \
+       bug-335131.2.cs \
+       bug-322722_patch_bx.2.cs        \
+       bug-322722_dyn_method_throw.2.cs        \
+       bug-389886-2.cs \
+       bug-349190.2.cs \
+       bug-389886-sre-generic-interface-instances.cs   \
+       bug-462592.cs   \
+       bug-575941.cs   \
+       bug-389886-3.cs \
+       constant-division.cs    \
+       dynamic-method-resurrection.cs  \
+       bug-80307.cs    \
+       assembly_append_ordering.cs     \
+       bug-544446.cs   \
+       bug-36848.cs    \
+       generic-marshalbyref.2.cs       \
+       stackframes-async.2.cs  \
+       transparentproxy.cs     \
+       bug-48015.cs    \
+       delegate9.cs    \
+       marshal-valuetypes.cs   \
+       xdomain-threads.cs      \
+       monitor.cs      \
+       generic-xdomain.2.cs    \
+       threadpool-exceptions7.cs       \
+       cross-domain.cs \
+       generic-unloading.2.cs  \
+       namedmutex-destroy-race.cs      \
+       thread6.cs      \
+       appdomain-threadpool-unload.cs
 
 # Disabled until ?mcs is fixed
 #      bug-331958.cs
@@ -470,7 +471,9 @@ BASE_TEST_CS_SRC_UNIVERSAL=         \
        bug-29585.cs    \
        priority.cs     \
        abort-cctor.cs  \
-       thread-native-exit.cs
+       thread-native-exit.cs \
+       reference-loader.cs \
+       thread-suspend-suspended.cs
 
 if INSTALL_MOBILE_STATIC
 BASE_TEST_CS_SRC= \
@@ -692,7 +695,6 @@ DISABLED_TESTS=                     \
        bug-459094.exe \
        delegate-invoke.exe \
        bug-Xamarin-5278.exe \
-       reference-loader.cs \
        $(PLATFORM_DISABLED_TESTS) \
        $(EXTRA_DISABLED_TESTS) \
        $(COOP_DISABLED_TESTS) \
@@ -881,7 +883,9 @@ bug-324535-il.dll$(PLATFORM_AOT_SUFFIX)     \
 bug-36848-a.dll$(PLATFORM_AOT_SUFFIX)  \
 bug-81691-b.dll$(PLATFORM_AOT_SUFFIX)  \
 bug-327438.2.exe$(PLATFORM_AOT_SUFFIX) \
-bug-81466-lib.dll$(PLATFORM_AOT_SUFFIX)
+bug-81466-lib.dll$(PLATFORM_AOT_SUFFIX)        \
+TestingReferenceAssembly.dll$(PLATFORM_AOT_SUFFIX)     \
+TestingReferenceReferenceAssembly.dll$(PLATFORM_AOT_SUFFIX)
 
 if INSTALL_MOBILE_STATIC
 prereqs: $(PREREQSI_IL_AOT) $(PREREQSI_CS_AOT) $(AOT_EXTRA_LIBS)
@@ -1112,7 +1116,7 @@ debug-casts:
        @$(MCS) -r:TestDriver.dll $(srcdir)/debug-casts.cs
        @$(RUNTIME) --debug=casts debug-casts.exe
 
-EXTRA_DIST += sgen-bridge.cs sgen-descriptors.cs sgen-gshared-vtype.cs sgen-bridge-major-fragmentation.cs sgen-domain-unload.cs sgen-weakref-stress.cs sgen-cementing-stress.cs sgen-case-23400.cs     finalizer-wait.cs critical-finalizers.cs sgen-domain-unload-2.cs sgen-suspend.cs sgen-new-threads-dont-join-stw.cs sgen-new-threads-dont-join-stw-2.cs sgen-bridge-xref.cs bug-17590.cs sgen-toggleref.cs sgen-bridge-gchandle.cs
+EXTRA_DIST += sgen-bridge.cs sgen-descriptors.cs sgen-gshared-vtype.cs sgen-bridge-major-fragmentation.cs sgen-domain-unload.cs sgen-weakref-stress.cs sgen-cementing-stress.cs sgen-case-23400.cs     finalizer-wait.cs critical-finalizers.cs sgen-domain-unload-2.cs sgen-suspend.cs sgen-new-threads-dont-join-stw.cs sgen-new-threads-dont-join-stw-2.cs sgen-new-threads-collect.cs sgen-bridge-xref.cs bug-17590.cs sgen-toggleref.cs sgen-bridge-gchandle.cs
 
 
 sgen-tests:
@@ -1137,6 +1141,7 @@ SGEN_REGULAR_TESTS_UNIVERSAL =    \
        sgen-case-23400.exe     \
        sgen-new-threads-dont-join-stw.exe      \
        sgen-new-threads-dont-join-stw-2.exe    \
+       sgen-new-threads-collect.exe    \
        gc-graystack-stress.exe \
        bug-17590.exe
 
diff --git a/mono/tests/appdomain-threadpool-unload.cs b/mono/tests/appdomain-threadpool-unload.cs
new file mode 100644 (file)
index 0000000..d8a7049
--- /dev/null
@@ -0,0 +1,52 @@
+
+using System;
+using System.Linq;
+using System.Threading;
+
+class Driver
+{
+       class ThreadPoolLauncherObject
+       {
+               public volatile int i = 0;
+
+               public ThreadPoolLauncherObject ()
+               {
+                       ThreadPool.QueueUserWorkItem (_ => { for (int i = 0; i < 10 * 1000 * 1000; ++i); }, null);
+               }
+       }
+
+       public static void Main ()
+       {
+               int count = 0;
+               object o = new object ();
+
+               foreach (var i in
+                       Enumerable.Range (0, 100)
+                               .AsParallel ().WithDegreeOfParallelism (Environment.ProcessorCount)
+                               .Select (i => {
+                                       AppDomain ad;
+
+                                       ad = AppDomain.CreateDomain ("testdomain" + i);
+                                       ad.CreateInstance (typeof (ThreadPoolLauncherObject).Assembly.FullName, typeof (ThreadPoolLauncherObject).FullName);
+
+                                       Thread.Sleep (10);
+
+                                       AppDomain.Unload (ad);
+
+                                       return i;
+                               })
+                               .Select (i => {
+                                       lock (o) {
+                                               count += 1;
+
+                                               Console.Write (".");
+                                               if (count % 25 == 0)
+                                                       Console.WriteLine ();
+                                       }
+
+                                       return i;
+                               })
+               ) {
+               }
+       }
+}
index 83f3ff71c297047f73fa0fa50fc1ee9d8e9bced4..7d0c812357d15c0c999445db9baeca94b97cb31f 100644 (file)
@@ -1,6 +1,9 @@
 using System;
 using System.Reflection;
 
+// this for test_0_missing_attr_on_assembly
+[assembly: MissingAttribute]
+
 public sealed class MyAttribute : Attribute
 {
        public Type Type { get; set; }
@@ -45,6 +48,15 @@ public class Bar {}
 
 class Tests {
 
+       public static int test_0_missing_attr_on_assembly () {
+               try {
+                       Assembly.GetExecutingAssembly().GetCustomAttributes (false);
+                       return 1;
+               } catch (TypeLoadException exn) {
+                       return 0;
+               }
+       }
+
        [My3 (new object[] { DisappearingEnum.V0 })]
        public static int test_0_missing_enum_arg_alt3 () {
                try {
diff --git a/mono/tests/sgen-new-threads-collect.cs b/mono/tests/sgen-new-threads-collect.cs
new file mode 100644 (file)
index 0000000..5deee6b
--- /dev/null
@@ -0,0 +1,51 @@
+
+using System;
+using System.Collections.Concurrent;
+using System.Threading;
+
+class Driver
+{
+       public static void Main ()
+       {
+               BlockingCollection<Thread> threads = new BlockingCollection<Thread> (new ConcurrentQueue<Thread> (), 128);
+
+               bool finished = false;
+
+               Thread gcThread = new Thread (() => {
+                       while (!finished) {
+                               GC.Collect ();
+                               Thread.Yield ();
+                       }
+               });
+
+               Thread joinThread = new Thread (() => {
+                       for (int i = 0; ; ++i) {
+                               Thread t = threads.Take ();
+                               if (t == null)
+                                       break;
+                               t.Join ();
+                               if ((i + 1) % (50) == 0)
+                                       Console.Write (".");
+                               if ((i + 1) % (50 * 50) == 0)
+                                       Console.WriteLine ();
+                       }
+               });
+
+               gcThread.Start ();
+               joinThread.Start ();
+
+               for (int i = 0; i < 10 * 1000; ++i) {
+                       Thread t = new Thread (() => { Thread.Yield (); });
+                       t.Start ();
+
+                       threads.Add (t);
+               }
+
+               threads.Add (null);
+
+               joinThread.Join ();
+
+               finished = true;
+               gcThread.Join ();
+       }
+}
\ No newline at end of file
diff --git a/mono/tests/thread-suspend-suspended.cs b/mono/tests/thread-suspend-suspended.cs
new file mode 100644 (file)
index 0000000..994042b
--- /dev/null
@@ -0,0 +1,43 @@
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Threading;
+
+class Driver
+{
+       public static void Main ()
+       {
+               bool finished = false;
+
+               Thread t1 = new Thread (() => {
+                       while (!finished) {}
+               });
+
+               Thread t2 = new Thread (() => {
+                       while (!finished) {
+                               GC.Collect ();
+                               Thread.Yield ();
+                       }
+               });
+
+               t1.Start ();
+               t2.Start ();
+
+               Thread.Sleep (10);
+
+               for (int i = 0; i < 50 * 40 * 20; ++i) {
+                       t1.Suspend ();
+                       Thread.Yield ();
+                       t1.Resume ();
+                       if ((i + 1) % (50) == 0)
+                               Console.Write (".");
+                       if ((i + 1) % (50 * 40) == 0)
+                               Console.WriteLine ();
+               }
+
+               finished = true;
+
+               t1.Join ();
+               t2.Join ();
+       }
+}
index abb24d9825f3ff143e20fa0cf73009455c72f1d8..712e2efa3816674170acfe4a2ca771dcb33d502e 100644 (file)
@@ -11,7 +11,7 @@
 #include "utils/mono-threads.h"
 #include "utils/mono-conc-hashtable.h"
 #include "utils/checked-build.h"
-#include "utils/w32handle.h"
+#include "metadata/w32handle.h"
 
 #include <stdlib.h>
 #include <string.h>
index add4c6a85fe6da74faa03cc6ddd9b7d720f4fbd1..ab301d1700bdb3b50958e69d3b858a9f34322f3c 100644 (file)
@@ -173,8 +173,6 @@ monoutils_sources = \
        parse.h \
        checked-build.c \
        checked-build.h \
-       w32handle.c \
-       w32handle.h \
        os-event.h
 
 arch_sources = 
index 1802ff79f5364d8301566717bc2da54b5bcad12d..179a4f7ed748199ed0f6ccc018a63957e7fde44a 100644 (file)
@@ -59,27 +59,30 @@ mono_mach_arch_get_mcontext_size ()
 }
 
 void
-mono_mach_arch_thread_state_to_mcontext (thread_state_t state, void *context)
+mono_mach_arch_thread_states_to_mcontext (thread_state_t state, thread_state_t fpstate, void *context)
 {
        x86_thread_state64_t *arch_state = (x86_thread_state64_t *) state;
+       x86_float_state64_t *arch_fpstate = (x86_float_state64_t *) fpstate;
        struct __darwin_mcontext64 *ctx = (struct __darwin_mcontext64 *) context;
-
        ctx->__ss = *arch_state;
+       ctx->__fs = *arch_fpstate;
 }
 
 void
-mono_mach_arch_mcontext_to_thread_state (void *context, thread_state_t state)
+mono_mach_arch_mcontext_to_thread_states (void *context, thread_state_t state, thread_state_t fpstate)
 {
        x86_thread_state64_t *arch_state = (x86_thread_state64_t *) state;
+       x86_float_state64_t *arch_fpstate = (x86_float_state64_t *) fpstate;
        struct __darwin_mcontext64 *ctx = (struct __darwin_mcontext64 *) context;
-
        *arch_state = ctx->__ss;
+       *arch_fpstate = ctx->__fs;
 }
 
 void
-mono_mach_arch_thread_state_to_mono_context (thread_state_t state, MonoContext *context)
+mono_mach_arch_thread_states_to_mono_context (thread_state_t state, thread_state_t fpstate, MonoContext *context)
 {
        x86_thread_state64_t *arch_state = (x86_thread_state64_t *) state;
+       x86_float_state64_t *arch_fpstate = (x86_float_state64_t *) fpstate;
        context->gregs [AMD64_RAX] = arch_state->__rax;
        context->gregs [AMD64_RBX] = arch_state->__rbx;
        context->gregs [AMD64_RCX] = arch_state->__rcx;
@@ -96,6 +99,22 @@ mono_mach_arch_thread_state_to_mono_context (thread_state_t state, MonoContext *
        context->gregs [AMD64_R14] = arch_state->__r14;
        context->gregs [AMD64_R15] = arch_state->__r15;
        context->gregs [AMD64_RIP] = arch_state->__rip;
+       context->fregs [AMD64_XMM0] = arch_fpstate->__fpu_xmm0;
+       context->fregs [AMD64_XMM1] = arch_fpstate->__fpu_xmm1;
+       context->fregs [AMD64_XMM2] = arch_fpstate->__fpu_xmm2;
+       context->fregs [AMD64_XMM3] = arch_fpstate->__fpu_xmm3;
+       context->fregs [AMD64_XMM4] = arch_fpstate->__fpu_xmm4;
+       context->fregs [AMD64_XMM5] = arch_fpstate->__fpu_xmm5;
+       context->fregs [AMD64_XMM6] = arch_fpstate->__fpu_xmm6;
+       context->fregs [AMD64_XMM7] = arch_fpstate->__fpu_xmm7;
+       context->fregs [AMD64_XMM8] = arch_fpstate->__fpu_xmm8;
+       context->fregs [AMD64_XMM9] = arch_fpstate->__fpu_xmm9;
+       context->fregs [AMD64_XMM10] = arch_fpstate->__fpu_xmm10;
+       context->fregs [AMD64_XMM11] = arch_fpstate->__fpu_xmm11;
+       context->fregs [AMD64_XMM12] = arch_fpstate->__fpu_xmm12;
+       context->fregs [AMD64_XMM13] = arch_fpstate->__fpu_xmm13;
+       context->fregs [AMD64_XMM14] = arch_fpstate->__fpu_xmm14;
+       context->fregs [AMD64_XMM15] = arch_fpstate->__fpu_xmm15;
 }
 
 int
@@ -104,23 +123,39 @@ mono_mach_arch_get_thread_state_size ()
        return sizeof (x86_thread_state64_t);
 }
 
+int
+mono_mach_arch_get_thread_fpstate_size ()
+{
+       return sizeof (x86_float_state64_t);
+}
+
 kern_return_t
-mono_mach_arch_get_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count)
+mono_mach_arch_get_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count, thread_state_t fpstate, mach_msg_type_number_t *fpcount)
 {
-       x86_thread_state64_t *arch_state = (x86_thread_state64_t *) state;
+       x86_thread_state64_t *arch_state = (x86_thread_state64_t *)state;
+       x86_float_state64_t *arch_fpstate = (x86_float_state64_t *)fpstate;
        kern_return_t ret;
 
        *count = x86_THREAD_STATE64_COUNT;
+       *fpcount = x86_FLOAT_STATE64_COUNT;
 
-       ret = thread_get_state (thread, x86_THREAD_STATE64, (thread_state_t) arch_state, count);
+       ret = thread_get_state (thread, x86_THREAD_STATE64, (thread_state_t)arch_state, count);
+       if (ret != KERN_SUCCESS)
+               return ret;
 
+       ret = thread_get_state (thread, x86_FLOAT_STATE64, (thread_state_t)arch_fpstate, fpcount);
        return ret;
 }
 
 kern_return_t
-mono_mach_arch_set_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count)
+mono_mach_arch_set_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count, thread_state_t fpstate, mach_msg_type_number_t fpcount)
 {
-       return thread_set_state (thread, x86_THREAD_STATE64, state, count);
+       kern_return_t ret;
+       ret = thread_set_state (thread, x86_THREAD_STATE64, state, count);
+       if (ret != KERN_SUCCESS)
+               return ret;
+       ret = thread_set_state (thread, x86_FLOAT_STATE64, fpstate, fpcount);
+       return ret;
 }
 
 void *
index d535fbc18ddce3689a7701acc1da0cd4eeca0492..a7fd9836d18326238294ffc4c48f2a4a3cf96032 100644 (file)
@@ -66,7 +66,7 @@ mono_mach_arch_get_mcontext_size ()
 }
 
 void
-mono_mach_arch_thread_state_to_mcontext (thread_state_t state, void *context)
+mono_mach_arch_thread_states_to_mcontext (thread_state_t state, thread_state_t fpstate, void *context)
 {
        arm_thread_state_t *arch_state = (arm_thread_state_t *) state;
        struct __darwin_mcontext *ctx = (struct __darwin_mcontext *) context;
@@ -75,7 +75,7 @@ mono_mach_arch_thread_state_to_mcontext (thread_state_t state, void *context)
 }
 
 void
-mono_mach_arch_mcontext_to_thread_state (void *context, thread_state_t state)
+mono_mach_arch_mcontext_to_thread_states (void *context, thread_state_t state, thread_state_t fpstate)
 {
        arm_thread_state_t *arch_state = (arm_thread_state_t *) state;
        struct __darwin_mcontext *ctx = (struct __darwin_mcontext *) context;
@@ -84,7 +84,7 @@ mono_mach_arch_mcontext_to_thread_state (void *context, thread_state_t state)
 }
 
 void
-mono_mach_arch_thread_state_to_mono_context (thread_state_t state, MonoContext *context)
+mono_mach_arch_thread_states_to_mono_context (thread_state_t state, thread_state_t fpstate, MonoContext *context)
 {
        int i;
        arm_thread_state_t *arch_state = (arm_thread_state_t *) state;
@@ -103,8 +103,14 @@ mono_mach_arch_get_thread_state_size ()
        return sizeof (arm_thread_state_t);
 }
 
+int
+mono_mach_arch_get_thread_fpstate_size ()
+{
+       g_assert_not_reached ();
+}
+
 kern_return_t
-mono_mach_arch_get_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count)
+mono_mach_arch_get_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count, thread_state_t fpstate, mach_msg_type_number_t *fpcount)
 {
 #if defined(HOST_WATCHOS)
        g_error ("thread_get_state() is not supported by this platform");
@@ -120,7 +126,7 @@ mono_mach_arch_get_thread_state (thread_port_t thread, thread_state_t state, mac
 }
 
 kern_return_t
-mono_mach_arch_set_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count)
+mono_mach_arch_set_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count, thread_state_t fpstate, mach_msg_type_number_t fpcount)
 {
 #if defined(HOST_WATCHOS)
        g_error ("thread_set_state() is not supported by this platform");
index 6483238d4565568b2695e254d7428c2c1426a70f..2035f485b14c22281602214440bc47fbaa8a30f6 100644 (file)
@@ -66,7 +66,7 @@ mono_mach_arch_get_mcontext_size ()
 }
 
 void
-mono_mach_arch_thread_state_to_mcontext (thread_state_t state, void *context)
+mono_mach_arch_thread_states_to_mcontext (thread_state_t state, thread_state_t fpstate, void *context)
 {
        arm_unified_thread_state_t *arch_state = (arm_unified_thread_state_t *) state;
        struct __darwin_mcontext64 *ctx = (struct __darwin_mcontext64 *) context;
@@ -75,7 +75,7 @@ mono_mach_arch_thread_state_to_mcontext (thread_state_t state, void *context)
 }
 
 void
-mono_mach_arch_mcontext_to_thread_state (void *context, thread_state_t state)
+mono_mach_arch_mcontext_to_thread_states (void *context, thread_state_t state, thread_state_t fpstate)
 {
        arm_unified_thread_state_t *arch_state = (arm_unified_thread_state_t *) state;
        struct __darwin_mcontext64 *ctx = (struct __darwin_mcontext64 *) context;
@@ -84,7 +84,7 @@ mono_mach_arch_mcontext_to_thread_state (void *context, thread_state_t state)
 }
 
 void
-mono_mach_arch_thread_state_to_mono_context (thread_state_t state, MonoContext *context)
+mono_mach_arch_thread_states_to_mono_context (thread_state_t state, thread_state_t fpstate, MonoContext *context)
 {
        int i;
        arm_unified_thread_state_t *arch_state = (arm_unified_thread_state_t *) state;
@@ -103,8 +103,14 @@ mono_mach_arch_get_thread_state_size ()
        return sizeof (arm_unified_thread_state_t);
 }
 
+int
+mono_mach_arch_get_thread_fpstate_size ()
+{
+       g_assert_not_reached ();
+}
+
 kern_return_t
-mono_mach_arch_get_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count)
+mono_mach_arch_get_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count, thread_state_t fpstate, mach_msg_type_number_t *fpcount)
 {
        arm_unified_thread_state_t *arch_state = (arm_unified_thread_state_t *) state;
        kern_return_t ret;
@@ -116,7 +122,7 @@ mono_mach_arch_get_thread_state (thread_port_t thread, thread_state_t state, mac
 }
 
 kern_return_t
-mono_mach_arch_set_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count)
+mono_mach_arch_set_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count, thread_state_t fpstate, mach_msg_type_number_t fpcount)
 {
        return thread_set_state (thread, ARM_UNIFIED_THREAD_STATE, state, count);
 }
index 20012550114610c911623f8a0cbdf9af0197c277..88eb187da4476b24dbb4980a851ab217ba1c1d5e 100644 (file)
@@ -35,19 +35,19 @@ mono_mach_arch_get_mcontext_size ()
 }
 
 void
-mono_mach_arch_thread_state_to_mcontext (thread_state_t state, void *context)
+mono_mach_arch_thread_states_to_mcontext (thread_state_t state, thread_state_t fpstate, void *context)
 {
        g_assert_not_reached ();
 }
 
 void
-mono_mach_arch_mcontext_to_thread_state (void *context, thread_state_t state)
+mono_mach_arch_mcontext_to_thread_states (void *context, thread_state_t state, thread_state_t fpstate)
 {
        g_assert_not_reached ();
 }
 
 void
-mono_mach_arch_thread_state_to_mono_context (thread_state_t state, MonoContext *context)
+mono_mach_arch_thread_states_to_mono_context (thread_state_t state, thread_state_t fpstate, MonoContext *context)
 {
        g_assert_not_reached ();
 }
@@ -58,14 +58,20 @@ mono_mach_arch_get_thread_state_size ()
        g_assert_not_reached ();
 }
 
+int
+mono_mach_arch_get_thread_fpstate_size ()
+{
+       g_assert_not_reached ();
+}
+
 kern_return_t
-mono_mach_arch_get_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count)
+mono_mach_arch_get_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count, thread_state_t fpstate, mach_msg_type_number_t *fpcount)
 {
        g_assert_not_reached ();
 }
 
 kern_return_t
-mono_mach_arch_set_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count)
+mono_mach_arch_set_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count, thread_state_t fpstate, mach_msg_type_number_t fpcount)
 {
        g_assert_not_reached ();        
 }
index 3e8b166eaf2b51a7dc69f49d889c896762d75732..a296254cd2cffb17f92947fdbc9dce54f7aa1c4e 100644 (file)
@@ -16,6 +16,9 @@
 #include "utils/mono-sigcontext.h"
 #include "mach-support.h"
 
+// For reg numbers
+#include <mono/arch/amd64/amd64-codegen.h>
+
 /* Known offsets used for TLS storage*/
 
 /* All OSX versions up to 10.8 */
@@ -55,27 +58,30 @@ mono_mach_arch_get_mcontext_size ()
 }
 
 void
-mono_mach_arch_thread_state_to_mcontext (thread_state_t state, void *context)
+mono_mach_arch_thread_states_to_mcontext (thread_state_t state, thread_state_t fpstate, void *context)
 {
        x86_thread_state32_t *arch_state = (x86_thread_state32_t *) state;
+       x86_float_state32_t *arch_fpstate = (x86_float_state32_t *) fpstate;
        struct __darwin_mcontext32 *ctx = (struct __darwin_mcontext32 *) context;
-
        ctx->__ss = *arch_state;
+       ctx->__fs = *arch_fpstate;
 }
 
 void
-mono_mach_arch_mcontext_to_thread_state (void *context, thread_state_t state)
+mono_mach_arch_mcontext_to_thread_states (void *context, thread_state_t state, thread_state_t fpstate)
 {
        x86_thread_state32_t *arch_state = (x86_thread_state32_t *) state;
+       x86_float_state32_t *arch_fpstate = (x86_float_state32_t *) fpstate;
        struct __darwin_mcontext32 *ctx = (struct __darwin_mcontext32 *) context;
-
        *arch_state = ctx->__ss;
+       *arch_fpstate = ctx->__fs;
 }
 
 void
-mono_mach_arch_thread_state_to_mono_context (thread_state_t state, MonoContext *context)
+mono_mach_arch_thread_states_to_mono_context (thread_state_t state, thread_state_t fpstate, MonoContext *context)
 {
        x86_thread_state32_t *arch_state = (x86_thread_state32_t *) state;
+       x86_float_state32_t *arch_fpstate = (x86_float_state32_t *) state;
        context->eax = arch_state->__eax;
        context->ebx = arch_state->__ebx;
        context->ecx = arch_state->__ecx;
@@ -85,38 +91,62 @@ mono_mach_arch_thread_state_to_mono_context (thread_state_t state, MonoContext *
        context->esi = arch_state->__edi;
        context->edi = arch_state->__esi;
        context->eip = arch_state->__eip;
+       context->fregs [X86_XMM0] = arch_fpstate->__fpu_xmm0;
+       context->fregs [X86_XMM1] = arch_fpstate->__fpu_xmm1;
+       context->fregs [X86_XMM2] = arch_fpstate->__fpu_xmm2;
+       context->fregs [X86_XMM3] = arch_fpstate->__fpu_xmm3;
+       context->fregs [X86_XMM4] = arch_fpstate->__fpu_xmm4;
+       context->fregs [X86_XMM5] = arch_fpstate->__fpu_xmm5;
+       context->fregs [X86_XMM6] = arch_fpstate->__fpu_xmm6;
+       context->fregs [X86_XMM7] = arch_fpstate->__fpu_xmm7;
 }
 
-
 int
 mono_mach_arch_get_thread_state_size ()
 {
        return sizeof (x86_thread_state32_t);
 }
 
+int
+mono_mach_arch_get_thread_fpstate_size ()
+{
+       return sizeof (x86_float_state32_t);
+}
+
 kern_return_t
-mono_mach_arch_get_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count)
+mono_mach_arch_get_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count, thread_state_t fpstate, mach_msg_type_number_t *fpcount)
 {
 #if defined(HOST_WATCHOS)
        g_error ("thread_get_state() is not supported by this platform");
 #else
        x86_thread_state32_t *arch_state = (x86_thread_state32_t *) state;
+       x86_float_state32_t *arch_fpstate = (x86_float_state32_t *) fpstate;
        kern_return_t ret;
 
        *count = x86_THREAD_STATE32_COUNT;
-       ret = thread_get_state (thread, x86_THREAD_STATE32, (thread_state_t) arch_state, count);
+       *fpcount = x86_FLOAT_STATE32_COUNT;
+
+       ret = thread_get_state (thread, x86_THREAD_STATE32, (thread_state_t)arch_state, count);
+       if (ret != KERN_SUCCESS)
+               return ret;
 
+       ret = thread_get_state (thread, x86_FLOAT_STATE32, (thread_state_t)arch_fpstate, fpcount);
        return ret;
 #endif
 }
 
 kern_return_t
-mono_mach_arch_set_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count)
+mono_mach_arch_set_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count, thread_state_t fpstate, mach_msg_type_number_t fpcount)
 {
 #if defined(HOST_WATCHOS)
        g_error ("thread_set_state() is not supported by this platform");
 #else
-       return thread_set_state (thread, x86_THREAD_STATE32, state, count);
+       kern_return_t ret;
+       ret = thread_set_state (thread, x86_THREAD_STATE32, state, count);
+       if (ret != KERN_SUCCESS)
+               return ret;
+       ret = thread_set_state (thread, x86_FLOAT_STATE32, fpstate, fpcount);
+       return ret;
 #endif 
 }
 
index abc135bd4eb8eb9987db2bb56f5bbf6aadf59093..9ac334c7171a729dbbf5bfbca16b6da1e4291087 100644 (file)
@@ -29,15 +29,17 @@ void *mono_mach_arch_get_sp (thread_state_t state);
 void mono_mach_init (pthread_key_t key);
 
 int mono_mach_arch_get_mcontext_size (void);
-void mono_mach_arch_thread_state_to_mcontext (thread_state_t state, void *context);
-void mono_mach_arch_mcontext_to_thread_state (void *context, thread_state_t state);
-void mono_mach_arch_thread_state_to_mono_context (thread_state_t state, MonoContext *context);
+void mono_mach_arch_thread_states_to_mcontext (thread_state_t state, thread_state_t fpstate, void *context);
+void mono_mach_arch_mcontext_to_thread_states (void *context, thread_state_t state, thread_state_t fpstate);
+void mono_mach_arch_thread_states_to_mono_context (thread_state_t state, thread_state_t fpstate, MonoContext *context);
 
+/* FIXME: Should return size_t, not int. */
 int mono_mach_arch_get_thread_state_size (void);
+int mono_mach_arch_get_thread_fpstate_size (void);
 kern_return_t mono_mach_get_threads (thread_act_array_t *threads, guint32 *count);
 kern_return_t mono_mach_free_threads (thread_act_array_t threads, guint32 count);
-kern_return_t mono_mach_arch_get_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count);
-kern_return_t mono_mach_arch_set_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count);
+kern_return_t mono_mach_arch_get_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count, thread_state_t fpstate, mach_msg_type_number_t *fpcount);
+kern_return_t mono_mach_arch_set_thread_states (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count, thread_state_t fpstate, mach_msg_type_number_t fpcount);
 void *mono_mach_arch_get_tls_value_from_thread (pthread_t thread, guint32 key);
 void *mono_mach_get_tls_address_from_thread (pthread_t thread, pthread_key_t key);
 
index 56948bdd901da23ae66edd34b6e7d19cf218c902..f29a67ca096690a978db2922ef8717ce7afa1920 100644 (file)
@@ -329,7 +329,7 @@ new_codechunk (CodeChunk *last, int dynamic, int size)
 {
        int minsize, flags = CODE_FLAG_MMAP;
        int chunk_size, bsize = 0;
-       int pagesize;
+       int pagesize, valloc_granule;
        CodeChunk *chunk;
        void *ptr;
 
@@ -338,12 +338,13 @@ new_codechunk (CodeChunk *last, int dynamic, int size)
 #endif
 
        pagesize = mono_pagesize ();
+       valloc_granule = mono_valloc_granule ();
 
        if (dynamic) {
                chunk_size = size;
                flags = CODE_FLAG_MALLOC;
        } else {
-               minsize = pagesize * MIN_PAGES;
+               minsize = MAX (pagesize * MIN_PAGES, valloc_granule);
                if (size < minsize)
                        chunk_size = minsize;
                else {
@@ -353,8 +354,8 @@ new_codechunk (CodeChunk *last, int dynamic, int size)
                        size += MIN_ALIGN - 1;
                        size &= ~(MIN_ALIGN - 1);
                        chunk_size = size;
-                       chunk_size += pagesize - 1;
-                       chunk_size &= ~ (pagesize - 1);
+                       chunk_size += valloc_granule - 1;
+                       chunk_size &= ~ (valloc_granule - 1);
                }
        }
 #ifdef BIND_ROOM
@@ -370,8 +371,8 @@ new_codechunk (CodeChunk *last, int dynamic, int size)
        if (chunk_size - size < bsize) {
                chunk_size = size + bsize;
                if (!dynamic) {
-                       chunk_size += pagesize - 1;
-                       chunk_size &= ~ (pagesize - 1);
+                       chunk_size += valloc_granule - 1;
+                       chunk_size &= ~ (valloc_granule - 1);
                }
        }
 #endif
index 632513d874f7c8069bd6a1ee0d57c23b1c06bdd3..3056c3afd3a63e31ed39b746dabc589cc0ccc6a1 100644 (file)
@@ -170,6 +170,26 @@ mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
        mctx->gregs [AMD64_R14] = UCONTEXT_REG_R14 (ctx);
        mctx->gregs [AMD64_R15] = UCONTEXT_REG_R15 (ctx);
        mctx->gregs [AMD64_RIP] = UCONTEXT_REG_RIP (ctx);
+
+#ifdef UCONTEXT_REG_XMM
+       mctx->fregs [0] = UCONTEXT_REG_XMM0 (ctx);
+       mctx->fregs [1] = UCONTEXT_REG_XMM1 (ctx);
+       mctx->fregs [2] = UCONTEXT_REG_XMM2 (ctx);
+       mctx->fregs [3] = UCONTEXT_REG_XMM3 (ctx);
+       mctx->fregs [4] = UCONTEXT_REG_XMM4 (ctx);
+       mctx->fregs [5] = UCONTEXT_REG_XMM5 (ctx);
+       mctx->fregs [6] = UCONTEXT_REG_XMM6 (ctx);
+       mctx->fregs [7] = UCONTEXT_REG_XMM7 (ctx);
+       mctx->fregs [8] = UCONTEXT_REG_XMM8 (ctx);
+       mctx->fregs [9] = UCONTEXT_REG_XMM9 (ctx);
+       mctx->fregs [10] = UCONTEXT_REG_XMM10 (ctx);
+       mctx->fregs [11] = UCONTEXT_REG_XMM11 (ctx);
+       mctx->fregs [12] = UCONTEXT_REG_XMM12 (ctx);
+       mctx->fregs [13] = UCONTEXT_REG_XMM13 (ctx);
+       mctx->fregs [14] = UCONTEXT_REG_XMM14 (ctx);
+       mctx->fregs [15] = UCONTEXT_REG_XMM15 (ctx);
+#endif
+
 #elif defined(HOST_WIN32)
        CONTEXT *context = (CONTEXT*)sigctx;
 
@@ -224,6 +244,26 @@ mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
        UCONTEXT_REG_R14 (ctx) = mctx->gregs [AMD64_R14];
        UCONTEXT_REG_R15 (ctx) = mctx->gregs [AMD64_R15];
        UCONTEXT_REG_RIP (ctx) = mctx->gregs [AMD64_RIP];
+
+#ifdef UCONTEXT_REG_XMM
+       UCONTEXT_REG_XMM0 (ctx) = mctx->fregs [0];
+       UCONTEXT_REG_XMM1 (ctx) = mctx->fregs [1];
+       UCONTEXT_REG_XMM2 (ctx) = mctx->fregs [2];
+       UCONTEXT_REG_XMM3 (ctx) = mctx->fregs [3];
+       UCONTEXT_REG_XMM4 (ctx) = mctx->fregs [4];
+       UCONTEXT_REG_XMM5 (ctx) = mctx->fregs [5];
+       UCONTEXT_REG_XMM6 (ctx) = mctx->fregs [6];
+       UCONTEXT_REG_XMM7 (ctx) = mctx->fregs [7];
+       UCONTEXT_REG_XMM8 (ctx) = mctx->fregs [8];
+       UCONTEXT_REG_XMM9 (ctx) = mctx->fregs [9];
+       UCONTEXT_REG_XMM10 (ctx) = mctx->fregs [10];
+       UCONTEXT_REG_XMM11 (ctx) = mctx->fregs [11];
+       UCONTEXT_REG_XMM12 (ctx) = mctx->fregs [12];
+       UCONTEXT_REG_XMM13 (ctx) = mctx->fregs [13];
+       UCONTEXT_REG_XMM14 (ctx) = mctx->fregs [14];
+       UCONTEXT_REG_XMM15 (ctx) = mctx->fregs [15];
+#endif
+
 #elif defined(HOST_WIN32)
        CONTEXT *context = (CONTEXT*)sigctx;
 
index 0a1bd524cfd42261ac798b6f0b2eb1b8c7fe726f..e8d52d23a289dfc2e2eb355c47df0c318e89ea1f 100644 (file)
 #include <signal.h>
 #endif
 
+#define MONO_CONTEXT_OFFSET(field, index, field_type) \
+    "i" (offsetof (MonoContext, field) + (index) * sizeof (field_type))
+
+#if defined(__APPLE__)
+typedef struct __darwin_xmm_reg MonoContextSimdReg;
+#endif
+
 /*
  * General notes about mono-context.
  * Each arch defines a MonoContext struct with all GPR regs + IP/PC.
@@ -87,6 +94,8 @@ struct sigcontext {
 # define SC_ESI esi
 #endif
 
+#include <mono/arch/x86/x86-codegen.h>
+
 typedef struct {
        mgreg_t eax;
        mgreg_t ebx;
@@ -97,6 +106,9 @@ typedef struct {
        mgreg_t esi;
        mgreg_t edi;
        mgreg_t eip;
+#ifdef __APPLE__
+    MonoContextSimdReg fregs [X86_XMM_NREG];
+#endif
 } MonoContext;
 
 #define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->eip = (mgreg_t)(ip); } while (0); 
@@ -129,18 +141,26 @@ typedef struct {
 #else
 #define MONO_CONTEXT_GET_CURRENT(ctx) \
        __asm__ __volatile__(   \
-       "movl $0x0, 0x00(%0)\n" \
-       "mov %%ebx, 0x04(%0)\n" \
-       "mov %%ecx, 0x08(%0)\n" \
-       "mov %%edx, 0x0c(%0)\n" \
-       "mov %%ebp, 0x10(%0)\n" \
-       "mov %%esp, 0x14(%0)\n" \
-       "mov %%esi, 0x18(%0)\n" \
-       "mov %%edi, 0x1c(%0)\n" \
+       "movl $0x0, %c[eax](%0)\n" \
+       "mov %%ebx, %c[ebx](%0)\n" \
+       "mov %%ecx, %c[ecx](%0)\n" \
+       "mov %%edx, %c[edx](%0)\n" \
+       "mov %%ebp, %c[ebp](%0)\n" \
+       "mov %%esp, %c[esp](%0)\n" \
+       "mov %%esi, %c[esi](%0)\n" \
+       "mov %%edi, %c[edi](%0)\n" \
        "call 1f\n"     \
        "1: pop 0x20(%0)\n"     \
        :       \
-       : "a" (&(ctx))  \
+       : "a" (&(ctx)), \
+               [eax] MONO_CONTEXT_OFFSET (eax, 0, mgreg_t), \
+               [ebx] MONO_CONTEXT_OFFSET (ebx, 0, mgreg_t), \
+               [ecx] MONO_CONTEXT_OFFSET (ecx, 0, mgreg_t), \
+               [edx] MONO_CONTEXT_OFFSET (edx, 0, mgreg_t), \
+               [ebp] MONO_CONTEXT_OFFSET (ebp, 0, mgreg_t), \
+               [esp] MONO_CONTEXT_OFFSET (esp, 0, mgreg_t), \
+               [esi] MONO_CONTEXT_OFFSET (esi, 0, mgreg_t), \
+               [edi] MONO_CONTEXT_OFFSET (edi, 0, mgreg_t) \
        : "memory")
 #endif
 
@@ -160,7 +180,11 @@ typedef struct {
 
 typedef struct {
        mgreg_t gregs [AMD64_NREG];
+#ifdef __APPLE__
+       MonoContextSimdReg fregs [AMD64_XMM_NREG];
+#else
        double fregs [AMD64_XMM_NREG];
+#endif
 } MonoContext;
 
 #define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->gregs [AMD64_RIP] = (mgreg_t)(ip); } while (0);
@@ -202,30 +226,98 @@ extern void mono_context_get_current (void *);
                : "rdx", "memory")
 #else
 
-#define MONO_CONTEXT_GET_CURRENT(ctx)  \
-       __asm__ __volatile__(   \
-               "movq $0x0,  0x00(%0)\n"        \
-               "movq %%rcx, 0x08(%0)\n"        \
-               "movq %%rdx, 0x10(%0)\n"        \
-               "movq %%rbx, 0x18(%0)\n"        \
-               "movq %%rsp, 0x20(%0)\n"        \
-               "movq %%rbp, 0x28(%0)\n"        \
-               "movq %%rsi, 0x30(%0)\n"        \
-               "movq %%rdi, 0x38(%0)\n"        \
-               "movq %%r8,  0x40(%0)\n"        \
-               "movq %%r9,  0x48(%0)\n"        \
-               "movq %%r10, 0x50(%0)\n"        \
-               "movq %%r11, 0x58(%0)\n"        \
-               "movq %%r12, 0x60(%0)\n"        \
-               "movq %%r13, 0x68(%0)\n"        \
-               "movq %%r14, 0x70(%0)\n"        \
-               "movq %%r15, 0x78(%0)\n"        \
-               /* "leaq (%%rip), %%rdx\n" is not understood by icc */  \
-               ".byte 0x48, 0x8d, 0x15, 0x00, 0x00, 0x00, 0x00\n" \
-               "movq %%rdx, 0x80(%0)\n"        \
-               :       \
-               : "a" (&(ctx))  \
-               : "rdx", "memory")
+#define MONO_CONTEXT_GET_CURRENT_GREGS(ctx) \
+       do { \
+               __asm__ __volatile__(   \
+                       "movq $0x0,  %c[rax](%0)\n"     \
+                       "movq %%rcx, %c[rcx](%0)\n"     \
+                       "movq %%rdx, %c[rdx](%0)\n"     \
+                       "movq %%rbx, %c[rbx](%0)\n"     \
+                       "movq %%rsp, %c[rsp](%0)\n"     \
+                       "movq %%rbp, %c[rbp](%0)\n"     \
+                       "movq %%rsi, %c[rsi](%0)\n"     \
+                       "movq %%rdi, %c[rdi](%0)\n"     \
+                       "movq %%r8,  %c[r8](%0)\n"      \
+                       "movq %%r9,  %c[r9](%0)\n"      \
+                       "movq %%r10, %c[r10](%0)\n"     \
+                       "movq %%r11, %c[r11](%0)\n"     \
+                       "movq %%r12, %c[r12](%0)\n"     \
+                       "movq %%r13, %c[r13](%0)\n"     \
+                       "movq %%r14, %c[r14](%0)\n"     \
+                       "movq %%r15, %c[r15](%0)\n"     \
+                       /* "leaq (%%rip), %%rdx\n" is not understood by icc */  \
+                       ".byte 0x48, 0x8d, 0x15, 0x00, 0x00, 0x00, 0x00\n" \
+                       "movq %%rdx, %c[rip](%0)\n"     \
+                       :       \
+                       : "a" (&(ctx)), \
+                               [rax] MONO_CONTEXT_OFFSET (gregs, AMD64_RAX, mgreg_t),  \
+                               [rcx] MONO_CONTEXT_OFFSET (gregs, AMD64_RCX, mgreg_t),  \
+                               [rdx] MONO_CONTEXT_OFFSET (gregs, AMD64_RDX, mgreg_t),  \
+                               [rbx] MONO_CONTEXT_OFFSET (gregs, AMD64_RBX, mgreg_t),  \
+                               [rsp] MONO_CONTEXT_OFFSET (gregs, AMD64_RSP, mgreg_t),  \
+                               [rbp] MONO_CONTEXT_OFFSET (gregs, AMD64_RBP, mgreg_t),  \
+                               [rsi] MONO_CONTEXT_OFFSET (gregs, AMD64_RSI, mgreg_t),  \
+                               [rdi] MONO_CONTEXT_OFFSET (gregs, AMD64_RDI, mgreg_t),  \
+                               [r8] MONO_CONTEXT_OFFSET (gregs, AMD64_R8, mgreg_t), \
+                               [r9] MONO_CONTEXT_OFFSET (gregs, AMD64_R9, mgreg_t), \
+                               [r10] MONO_CONTEXT_OFFSET (gregs, AMD64_R10, mgreg_t),  \
+                               [r11] MONO_CONTEXT_OFFSET (gregs, AMD64_R11, mgreg_t),  \
+                               [r12] MONO_CONTEXT_OFFSET (gregs, AMD64_R12, mgreg_t),  \
+                               [r13] MONO_CONTEXT_OFFSET (gregs, AMD64_R13, mgreg_t),  \
+                               [r14] MONO_CONTEXT_OFFSET (gregs, AMD64_R14, mgreg_t),  \
+                               [r15] MONO_CONTEXT_OFFSET (gregs, AMD64_R15, mgreg_t),  \
+                               [rip] MONO_CONTEXT_OFFSET (gregs, AMD64_RIP, mgreg_t)   \
+                       : "rdx", "memory");     \
+       } while (0)
+
+#ifdef UCONTEXT_REG_XMM
+#define MONO_CONTEXT_GET_CURRENT_FREGS(ctx) \
+       do { \
+               __asm__ __volatile__ ( \
+                       "movups %%xmm0, %c[xmm0](%0)\n" \
+                       "movups %%xmm1, %c[xmm1](%0)\n" \
+                       "movups %%xmm2, %c[xmm2](%0)\n" \
+                       "movups %%xmm3, %c[xmm3](%0)\n" \
+                       "movups %%xmm4, %c[xmm4](%0)\n" \
+                       "movups %%xmm5, %c[xmm5](%0)\n" \
+                       "movups %%xmm6, %c[xmm6](%0)\n" \
+                       "movups %%xmm7, %c[xmm7](%0)\n" \
+                       "movups %%xmm8, %c[xmm8](%0)\n" \
+                       "movups %%xmm9, %c[xmm9](%0)\n" \
+                       "movups %%xmm10, %c[xmm10](%0)\n"       \
+                       "movups %%xmm11, %c[xmm11](%0)\n"       \
+                       "movups %%xmm12, %c[xmm12](%0)\n"       \
+                       "movups %%xmm12, %c[xmm12](%0)\n"       \
+                       "movups %%xmm14, %c[xmm14](%0)\n"       \
+                       "movups %%xmm15, %c[xmm15](%0)\n"       \
+                       : \
+                       : "a" (&(ctx)), \
+                               [xmm0] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM0, MonoContextSimdReg), \
+                               [xmm1] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM1, MonoContextSimdReg), \
+                               [xmm2] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM2, MonoContextSimdReg), \
+                               [xmm3] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM3, MonoContextSimdReg), \
+                               [xmm4] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM4, MonoContextSimdReg), \
+                               [xmm5] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM5, MonoContextSimdReg), \
+                               [xmm6] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM6, MonoContextSimdReg), \
+                               [xmm7] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM7, MonoContextSimdReg), \
+                               [xmm8] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM8, MonoContextSimdReg), \
+                               [xmm9] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM9, MonoContextSimdReg), \
+                               [xmm10] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM10, MonoContextSimdReg), \
+                               [xmm11] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM11, MonoContextSimdReg), \
+                               [xmm12] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM12, MonoContextSimdReg), \
+                               [xmm13] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM13, MonoContextSimdReg), \
+                               [xmm14] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM14, MonoContextSimdReg), \
+                               [xmm15] MONO_CONTEXT_OFFSET (fregs, AMD64_XMM15, MonoContextSimdReg));  \
+       } while (0)
+#else
+#define MONO_CONTEXT_GET_CURRENT_FREGS(ctx)
+#endif
+
+#define MONO_CONTEXT_GET_CURRENT(ctx) \
+    do {       \
+               MONO_CONTEXT_GET_CURRENT_GREGS(ctx);    \
+               MONO_CONTEXT_GET_CURRENT_FREGS(ctx);    \
+       } while (0)
 #endif
 
 #define MONO_ARCH_HAS_MONO_CONTEXT 1
@@ -264,15 +356,15 @@ typedef struct {
                "push {r0}\n"                           \
                "push {r1}\n"                           \
                "mov r0, %0\n"                          \
-               "ldr r1, [sp, #4]\n"                    \
-               "str r1, [r0]!\n"                       \
-               "ldr r1, [sp, #0]\n"                    \
-               "str r1, [r0]!\n"                       \
+               "ldr r1, [sp, #4]\n"            \
+               "str r1, [r0], #4\n"            \
+               "ldr r1, [sp, #0]\n"            \
+               "str r1, [r0], #4\n"            \
                "stmia r0!, {r2-r12}\n"         \
-               "str sp, [r0]!\n"                       \
-               "str lr, [r0]!\n"                       \
+               "str sp, [r0], #4\n"            \
+               "str lr, [r0], #4\n"            \
                "mov r1, pc\n"                          \
-               "str r1, [r0]!\n"                       \
+               "str r1, [r0], #4\n"            \
                "pop {r1}\n"                            \
                "pop {r0}\n"                            \
                :                                                       \
@@ -294,6 +386,11 @@ typedef struct {
        mgreg_t regs [32];
        double fregs [32];
        mgreg_t pc;
+       /*
+        * fregs might not be initialized if this context was created from a
+        * ucontext.
+        */
+       mgreg_t has_fregs;
 } MonoContext;
 
 #define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->pc = (mgreg_t)ip; } while (0)
@@ -313,7 +410,7 @@ typedef struct {
        thread_port_t self = mach_thread_self ();       \
        kern_return_t ret = thread_get_state (self, state_flavor, (thread_state_t) &thread_state, &state_count);        \
        g_assert (ret == 0);    \
-       mono_mach_arch_thread_state_to_mono_context ((thread_state_t)&thread_state, &ctx); \
+       mono_mach_arch_thread_states_to_mono_context ((thread_state_t)&thread_state, (thread_state_t)NULL, &ctx); \
        mach_port_deallocate (current_task (), self);   \
 } while (0);
 
index 2c161c6c4ab6f192d7de9effde0c77e2dfe5238a..d0b6072bece42f0bf94070df2fdad50ed88d5df9 100644 (file)
@@ -27,10 +27,22 @@ mono_pagesize (void)
        if (saved_pagesize)
                return saved_pagesize;
        GetSystemInfo (&info);
-       saved_pagesize = info.dwAllocationGranularity;
+       saved_pagesize = info.dwPageSize;
        return saved_pagesize;
 }
 
+int
+mono_valloc_granule (void)
+{
+       SYSTEM_INFO info;
+       static int saved_valloc_granule = 0;
+       if (saved_valloc_granule)
+               return saved_valloc_granule;
+       GetSystemInfo (&info);
+       saved_valloc_granule = info.dwAllocationGranularity;
+       return saved_valloc_granule;
+}
+
 int
 mono_mmap_win_prot_from_flags (int flags)
 {
index 91fe5a12def4517d7c1d364df7117cef53aa988f..10a190ff9b059383a5705e6e0e5d765a79a7122d 100644 (file)
@@ -155,6 +155,12 @@ mono_pagesize (void)
        return saved_pagesize;
 }
 
+int
+mono_valloc_granule (void)
+{
+       return mono_pagesize ();
+}
+
 static int
 prot_from_flags (int flags)
 {
@@ -364,6 +370,12 @@ mono_pagesize (void)
        return 4096;
 }
 
+int
+mono_valloc_granule (void)
+{
+       return mono_pagesize ();
+}
+
 void*
 mono_valloc (void *addr, size_t length, int flags, MonoMemAccountType type)
 {
index d441751c802da5bb60f36c29d638377b7f426c26..1b3b1d63af9fae39922ffe6aaceb51b3266bf3e6 100644 (file)
@@ -49,6 +49,7 @@ MONO_API int          mono_file_map_fd    (MonoFileMap *fmap);
 MONO_API int          mono_file_map_close (MonoFileMap *fmap);
 
 MONO_API int   mono_pagesize   (void);
+MONO_API int   mono_valloc_granule (void);
 MONO_API void* mono_valloc     (void *addr, size_t length, int flags, MonoMemAccountType type);
 MONO_API void* mono_valloc_aligned (size_t length, size_t alignment, int flags, MonoMemAccountType type);
 MONO_API int   mono_vfree      (void *addr, size_t length, MonoMemAccountType type);
index 3c2f79b58c37e99ac92e90325b6f603118182aaa..643bb4d7709a9f7299bd8b039e7665d6e058921c 100644 (file)
@@ -173,6 +173,23 @@ typedef struct ucontext {
        #define UCONTEXT_REG_R13(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__ss.__r13)
        #define UCONTEXT_REG_R14(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__ss.__r14)
        #define UCONTEXT_REG_R15(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__ss.__r15)
+       #define UCONTEXT_REG_XMM
+       #define UCONTEXT_REG_XMM0(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm0)
+       #define UCONTEXT_REG_XMM1(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm1)
+       #define UCONTEXT_REG_XMM2(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm2)
+       #define UCONTEXT_REG_XMM3(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm3)
+       #define UCONTEXT_REG_XMM4(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm4)
+       #define UCONTEXT_REG_XMM5(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm5)
+       #define UCONTEXT_REG_XMM6(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm6)
+       #define UCONTEXT_REG_XMM7(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm7)
+       #define UCONTEXT_REG_XMM8(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm8)
+       #define UCONTEXT_REG_XMM9(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm9)
+       #define UCONTEXT_REG_XMM10(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm10)
+       #define UCONTEXT_REG_XMM11(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm11)
+       #define UCONTEXT_REG_XMM12(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm12)
+       #define UCONTEXT_REG_XMM13(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm13)
+       #define UCONTEXT_REG_XMM14(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm14)
+       #define UCONTEXT_REG_XMM15(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__fs.__fpu_xmm15)
 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
        #define UCONTEXT_REG_RAX(ctx) (((ucontext_t*)(ctx))->uc_mcontext.mc_rax)
        #define UCONTEXT_REG_RBX(ctx) (((ucontext_t*)(ctx))->uc_mcontext.mc_rbx)
@@ -229,7 +246,7 @@ typedef struct ucontext {
        #define UCONTEXT_REG_R14(ctx) (((ucontext_t*)(ctx))->sc_r14)
        #define UCONTEXT_REG_R15(ctx) (((ucontext_t*)(ctx))->sc_r15)
 #elif !defined(HOST_WIN32)
-#define UCONTEXT_GREGS(ctx)    ((guint64*)&(((ucontext_t*)(ctx))->uc_mcontext.gregs))
+       #define UCONTEXT_GREGS(ctx)     ((guint64*)&(((ucontext_t*)(ctx))->uc_mcontext.gregs))
 #endif
 
 #ifdef UCONTEXT_GREGS
index 22b232ad4d523edca38df6d2ae230e34990251a3..7f2748536830157d0179423a510f6c7e21e9b6da 100644 (file)
@@ -135,7 +135,7 @@ mono_threads_state_poll_with_info (MonoThreadInfo *info)
        /* commit the saved state and notify others if needed */
        switch (mono_threads_transition_state_poll (info)) {
        case SelfSuspendResumed:
-               return;
+               break;
        case SelfSuspendWait:
                mono_thread_info_wait_for_resume (info);
                break;
@@ -144,6 +144,12 @@ mono_threads_state_poll_with_info (MonoThreadInfo *info)
                mono_thread_info_wait_for_resume (info);
                break;
        }
+
+       if (info->async_target) {
+               info->async_target (info->user_data);
+               info->async_target = NULL;
+               info->user_data = NULL;
+       }
 }
 
 static volatile gpointer* dummy_global;
index b696064decdc986ea5305ef39a4aa4ee5a45242e..fdf18bb1891eeb47c08ec7e6176341912fe57b03 100644 (file)
@@ -117,8 +117,8 @@ mono_threads_suspend_begin_async_resume (MonoThreadInfo *info)
 
        if (info->async_target) {
                MonoContext tmp = info->thread_saved_state [ASYNC_SUSPEND_STATE_INDEX].ctx;
-               mach_msg_type_number_t num_state;
-               thread_state_t state;
+               mach_msg_type_number_t num_state, num_fpstate;
+               thread_state_t state, fpstate;
                ucontext_t uctx;
                mcontext_t mctx;
 
@@ -127,23 +127,24 @@ mono_threads_suspend_begin_async_resume (MonoThreadInfo *info)
                info->async_target = (void (*)(void *)) info->user_data;
 
                state = (thread_state_t) alloca (mono_mach_arch_get_thread_state_size ());
+               fpstate = (thread_state_t) alloca (mono_mach_arch_get_thread_fpstate_size ());
                mctx = (mcontext_t) alloca (mono_mach_arch_get_mcontext_size ());
 
                do {
-                       ret = mono_mach_arch_get_thread_state (info->native_handle, state, &num_state);
+                       ret = mono_mach_arch_get_thread_states (info->native_handle, state, &num_state, fpstate, &num_fpstate);
                } while (ret == KERN_ABORTED);
 
                if (ret != KERN_SUCCESS)
                        return FALSE;
 
-               mono_mach_arch_thread_state_to_mcontext (state, mctx);
+               mono_mach_arch_thread_states_to_mcontext (state, fpstate, mctx);
                uctx.uc_mcontext = mctx;
                mono_monoctx_to_sigctx (&tmp, &uctx);
 
-               mono_mach_arch_mcontext_to_thread_state (mctx, state);
+               mono_mach_arch_mcontext_to_thread_states (mctx, state, fpstate);
 
                do {
-                       ret = mono_mach_arch_set_thread_state (info->native_handle, state, num_state);
+                       ret = mono_mach_arch_set_thread_states (info->native_handle, state, num_state, fpstate, num_fpstate);
                } while (ret == KERN_ABORTED);
 
                if (ret != KERN_SUCCESS)
index be440711fb3bfcbdf3be365bd25876045dfe8bf5..5447a8fe93f412b9eef902ff644c9246197a7830 100644 (file)
@@ -17,7 +17,6 @@
 #include <mono/utils/mono-threads.h>
 #include <mono/utils/mono-coop-semaphore.h>
 #include <mono/metadata/gc-internals.h>
-#include <mono/utils/w32handle.h>
 #include <mono/utils/mono-threads-debug.h>
 
 #include <errno.h>
@@ -36,23 +35,6 @@ extern int tkill (pid_t tid, int signal);
 
 #include <sys/resource.h>
 
-#if defined(__native_client__)
-void nacl_shutdown_gc_thread(void);
-#endif
-
-void
-mono_threads_platform_register (MonoThreadInfo *info)
-{
-       gpointer thread_handle;
-
-       thread_handle = mono_w32handle_new (MONO_W32HANDLE_THREAD, NULL);
-       if (thread_handle == INVALID_HANDLE_VALUE)
-               g_error ("%s: failed to create handle", __func__);
-
-       g_assert (!info->handle);
-       info->handle = thread_handle;
-}
-
 int
 mono_threads_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_data, gsize* const stack_size, MonoNativeThreadId *out_tid)
 {
@@ -158,25 +140,9 @@ mono_threads_platform_yield (void)
 }
 
 void
-mono_threads_platform_exit (int exit_code)
+mono_threads_platform_exit (gsize exit_code)
 {
-#if defined(__native_client__)
-       nacl_shutdown_gc_thread();
-#endif
-
-       mono_thread_info_detach ();
-
-       pthread_exit (NULL);
-}
-
-void
-mono_threads_platform_unregister (MonoThreadInfo *info)
-{
-       g_assert (info->handle);
-
-       /* The thread is no longer active, so unref it */
-       mono_w32handle_unref (info->handle);
-       info->handle = NULL;
+       pthread_exit ((gpointer) exit_code);
 }
 
 int
@@ -193,28 +159,6 @@ mono_threads_get_max_stack_size (void)
        return (int)lim.rlim_max;
 }
 
-gpointer
-mono_threads_platform_duplicate_handle (MonoThreadInfo *info)
-{
-       g_assert (info->handle);
-       mono_w32handle_ref (info->handle);
-       return info->handle;
-}
-
-HANDLE
-mono_threads_platform_open_thread_handle (HANDLE handle, MonoNativeThreadId tid)
-{
-       mono_w32handle_ref (handle);
-
-       return handle;
-}
-
-void
-mono_threads_platform_close_thread_handle (HANDLE handle)
-{
-       mono_w32handle_unref (handle);
-}
-
 int
 mono_threads_pthread_kill (MonoThreadInfo *info, int signum)
 {
@@ -311,56 +255,6 @@ mono_native_thread_join (MonoNativeThreadId tid)
        return !pthread_join (tid, &res);
 }
 
-void
-mono_threads_platform_set_exited (gpointer handle)
-{
-       int thr_ret;
-
-       g_assert (handle);
-       if (mono_w32handle_issignalled (handle))
-               g_error ("%s: handle %p thread %p has already exited, it's handle is signalled", __func__, handle, mono_native_thread_id_get ());
-       if (mono_w32handle_get_type (handle) == MONO_W32HANDLE_UNUSED)
-               g_error ("%s: handle %p thread %p has already exited, it's handle type is 'unused'", __func__, handle, mono_native_thread_id_get ());
-
-       thr_ret = mono_w32handle_lock_handle (handle);
-       g_assert (thr_ret == 0);
-
-       mono_w32handle_set_signal_state (handle, TRUE, TRUE);
-
-       thr_ret = mono_w32handle_unlock_handle (handle);
-       g_assert (thr_ret == 0);
-}
-
-static const gchar* thread_typename (void)
-{
-       return "Thread";
-}
-
-static gsize thread_typesize (void)
-{
-       return 0;
-}
-
-static MonoW32HandleOps thread_ops = {
-       NULL,                           /* close */
-       NULL,                           /* signal */
-       NULL,                           /* own */
-       NULL,                           /* is_owned */
-       NULL,                           /* special_wait */
-       NULL,                           /* prewait */
-       NULL,                           /* details */
-       thread_typename,        /* typename */
-       thread_typesize,        /* typesize */
-};
-
-void
-mono_threads_platform_init (void)
-{
-       mono_w32handle_register_ops (MONO_W32HANDLE_THREAD, &thread_ops);
-
-       mono_w32handle_register_capabilities (MONO_W32HANDLE_THREAD, MONO_W32HANDLE_CAP_WAIT);
-}
-
 #endif /* defined(_POSIX_VERSION) || defined(__native_client__) */
 
 #if defined(USE_POSIX_BACKEND)
@@ -392,8 +286,13 @@ This begins async resume. This function must do the following:
 gboolean
 mono_threads_suspend_begin_async_resume (MonoThreadInfo *info)
 {
-       mono_threads_add_to_pending_operation_set (info);
-       return mono_threads_pthread_kill (info, mono_threads_suspend_get_restart_signal ()) == 0;
+       int sig = mono_threads_suspend_get_restart_signal ();
+
+       if (!mono_threads_pthread_kill (info, sig)) {
+               mono_threads_add_to_pending_operation_set (info);
+               return TRUE;
+       }
+       return FALSE;
 }
 
 void
index 9a8a93b96948afc523515992b7737553166263b3..f3f160b30c93e2a0146638caff40639a338b45f7 100644 (file)
@@ -189,22 +189,6 @@ mono_threads_suspend_get_abort_signal (void)
 
 #if defined (HOST_WIN32)
 
-void
-mono_threads_platform_register (MonoThreadInfo *info)
-{
-       HANDLE thread_handle;
-
-       thread_handle = GetCurrentThread ();
-       g_assert (thread_handle);
-
-       /* The handle returned by GetCurrentThread () is a pseudo handle, so it can't
-        * be used to refer to the thread from other threads for things like aborting. */
-       DuplicateHandle (GetCurrentProcess (), thread_handle, GetCurrentProcess (), &thread_handle, THREAD_ALL_ACCESS, TRUE, 0);
-
-       g_assert (!info->handle);
-       info->handle = thread_handle;
-}
-
 int
 mono_threads_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_data, gsize* const stack_size, MonoNativeThreadId *out_tid)
 {
@@ -312,21 +296,11 @@ mono_threads_platform_yield (void)
 }
 
 void
-mono_threads_platform_exit (int exit_code)
+mono_threads_platform_exit (gsize exit_code)
 {
-       mono_thread_info_detach ();
        ExitThread (exit_code);
 }
 
-void
-mono_threads_platform_unregister (MonoThreadInfo *info)
-{
-       g_assert (info->handle);
-
-       CloseHandle (info->handle);
-       info->handle = NULL;
-}
-
 int
 mono_threads_get_max_stack_size (void)
 {
@@ -334,29 +308,6 @@ mono_threads_get_max_stack_size (void)
        return INT_MAX;
 }
 
-gpointer
-mono_threads_platform_duplicate_handle (MonoThreadInfo *info)
-{
-       HANDLE thread_handle;
-
-       g_assert (info->handle);
-       DuplicateHandle (GetCurrentProcess (), info->handle, GetCurrentProcess (), &thread_handle, THREAD_ALL_ACCESS, TRUE, 0);
-
-       return thread_handle;
-}
-
-HANDLE
-mono_threads_platform_open_thread_handle (HANDLE handle, MonoNativeThreadId tid)
-{
-       return OpenThread (THREAD_ALL_ACCESS, TRUE, tid);
-}
-
-void
-mono_threads_platform_close_thread_handle (HANDLE handle)
-{
-       CloseHandle (handle);
-}
-
 #if defined(_MSC_VER)
 const DWORD MS_VC_EXCEPTION=0x406D1388;
 #pragma pack(push,8)
@@ -389,14 +340,4 @@ mono_native_thread_set_name (MonoNativeThreadId tid, const char *name)
 #endif
 }
 
-void
-mono_threads_platform_set_exited (gpointer handle)
-{
-}
-
-void
-mono_threads_platform_init (void)
-{
-}
-
 #endif
index 49031c860e505d51a23f97b3fe86ee4f3cb1f160..d97797e8b68829c5da42b402ae751de6a11cd6e1 100644 (file)
@@ -30,6 +30,7 @@
 #include <mono/utils/mono-coop-semaphore.h>
 #include <mono/utils/mono-threads-coop.h>
 #include <mono/utils/mono-threads-debug.h>
+#include <mono/utils/os-event.h>
 
 #include <errno.h>
 
@@ -347,6 +348,10 @@ register_thread (MonoThreadInfo *info, gpointer baseptr)
        mono_thread_info_set_tid (info, mono_native_thread_id_get ());
        info->small_id = small_id;
 
+       info->handle = g_new0 (MonoThreadHandle, 1);
+       info->handle->ref = 1;
+       mono_os_event_init (&info->handle->event, TRUE, FALSE);
+
        mono_os_sem_init (&info->resume_semaphore, 0);
 
        /*set TLS early so SMR works */
@@ -371,7 +376,6 @@ register_thread (MonoThreadInfo *info, gpointer baseptr)
 
        info->stackdata = g_byte_array_new ();
 
-       mono_threads_platform_register (info);
        mono_threads_suspend_register (info);
 
        /*
@@ -392,6 +396,9 @@ register_thread (MonoThreadInfo *info, gpointer baseptr)
 static void
 mono_thread_info_suspend_lock_with_info (MonoThreadInfo *info);
 
+static void
+mono_threads_signal_thread_handle (MonoThreadHandle* thread_handle);
+
 static void
 unregister_thread (void *arg)
 {
@@ -426,7 +433,7 @@ unregister_thread (void *arg)
 
        /* we need to duplicate it, as the info->handle is going
         * to be closed when unregistering from the platform */
-       handle = mono_threads_platform_duplicate_handle (info);
+       handle = mono_threads_open_thread_handle (info->handle);
 
        /*
        First perform the callback that requires no locks.
@@ -447,7 +454,10 @@ unregister_thread (void *arg)
        if (threads_callbacks.thread_unregister)
                threads_callbacks.thread_unregister (info);
 
-       mono_threads_platform_unregister (info);
+       /* The thread is no longer active, so unref its handle */
+       mono_threads_close_thread_handle (info->handle);
+       info->handle = NULL;
+
        result = mono_thread_info_remove (info);
        g_assert (result);
        mono_threads_transition_detach (info);
@@ -463,12 +473,9 @@ unregister_thread (void *arg)
 
        mono_thread_small_id_free (small_id);
 
-       /* Signal the w32handle. It can be done as late as here
-        * because w32handle does not access the current MonoThreadInfo,
-        * neither does it switch state to BLOCKING. */
-       mono_threads_platform_set_exited (handle);
+       mono_threads_signal_thread_handle (handle);
 
-       mono_threads_platform_close_thread_handle (handle);
+       mono_threads_close_thread_handle (handle);
 }
 
 static void
@@ -689,7 +696,6 @@ mono_threads_init (MonoThreadInfoCallbacks *callbacks, size_t info_size)
 
        mono_lls_init (&thread_list, NULL);
        mono_thread_smr_init ();
-       mono_threads_platform_init ();
        mono_threads_suspend_init ();
        mono_threads_suspend_init_signals ();
        mono_threads_coop_init ();
@@ -723,6 +729,8 @@ To finish suspending, call mono_suspend_check.
 void
 mono_thread_info_begin_self_suspend (void)
 {
+       g_assert (!mono_threads_is_coop_enabled ());
+
        MonoThreadInfo *info = mono_thread_info_current_unchecked ();
        if (!info)
                return;
@@ -736,6 +744,8 @@ mono_thread_info_end_self_suspend (void)
 {
        MonoThreadInfo *info;
 
+       g_assert (!mono_threads_is_coop_enabled ());
+
        info = mono_thread_info_current ();
        if (!info)
                return;
@@ -869,6 +879,9 @@ is_thread_in_critical_region (MonoThreadInfo *info)
        if (stack_start < info->stack_start_limit || stack_start >= info->stack_end)
                return TRUE;
 
+       if (threads_callbacks.ip_in_critical_region)
+               return threads_callbacks.ip_in_critical_region ((MonoDomain *) state->unwind_data [MONO_UNWIND_DATA_DOMAIN], (char *) MONO_CONTEXT_GET_IP (&state->ctx));
+
        ji = mono_jit_info_table_find (
                (MonoDomain *) state->unwind_data [MONO_UNWIND_DATA_DOMAIN],
                (char *) MONO_CONTEXT_GET_IP (&state->ctx));
@@ -912,7 +925,7 @@ suspend_sync (MonoNativeThreadId tid, gboolean interrupt_kernel)
                }
                break;
        case AsyncSuspendBlocking:
-               if (interrupt_kernel)
+               if (interrupt_kernel && mono_threads_suspend_needs_abort_syscall ())
                        mono_threads_suspend_abort_syscall (info);
 
                break;
@@ -992,6 +1005,7 @@ mono_thread_info_safe_suspend_and_run (MonoNativeThreadId id, gboolean interrupt
                mono_threads_wait_pending_operations ();
                break;
        case KeepSuspended:
+               g_assert (!mono_threads_is_coop_enabled ());
                break;
        default:
                g_error ("Invalid suspend_and_run callback return value %d", result);
@@ -1128,7 +1142,7 @@ typedef struct {
        gpointer start_routine_arg;
        gint32 priority;
        MonoCoopSem registered;
-       gpointer handle;
+       MonoThreadHandle *handle;
 } CreateThreadData;
 
 static gsize WINAPI
@@ -1138,7 +1152,7 @@ inner_start_thread (gpointer data)
        MonoThreadInfo *info;
        MonoThreadStart start_routine;
        gpointer start_routine_arg;
-       guint32 start_routine_res;
+       gsize start_routine_res;
        gsize dummy;
 
        thread_data = (CreateThreadData*) data;
@@ -1150,7 +1164,7 @@ inner_start_thread (gpointer data)
        info = mono_thread_info_attach (&dummy);
        info->runtime_thread = TRUE;
 
-       thread_data->handle = mono_thread_info_duplicate_handle (info);
+       thread_data->handle = mono_threads_open_thread_handle (info->handle);
 
        mono_coop_sem_post (&thread_data->registered);
 
@@ -1165,7 +1179,7 @@ inner_start_thread (gpointer data)
        /* Run the actual main function of the thread */
        start_routine_res = start_routine (start_routine_arg);
 
-       mono_threads_platform_exit (start_routine_res);
+       mono_thread_info_exit (start_routine_res);
 
        g_assert_not_reached ();
 }
@@ -1176,12 +1190,12 @@ inner_start_thread (gpointer data)
  *   Create a new thread executing START with argument ARG. Store its id into OUT_TID.
  * Returns: a windows or io-layer handle for the thread.
  */
-HANDLE
+MonoThreadHandle*
 mono_threads_create_thread (MonoThreadStart start, gpointer arg, gsize * const stack_size, MonoNativeThreadId *out_tid)
 {
        CreateThreadData *thread_data;
        gint res;
-       gpointer ret;
+       MonoThreadHandle *ret;
 
        thread_data = g_new0 (CreateThreadData, 1);
        thread_data->ref = 2;
@@ -1401,6 +1415,10 @@ mono_thread_info_tls_set (THREAD_INFO_TYPE *info, MonoTlsKey key, gpointer value
        ((MonoThreadInfo*)info)->tls [key] = value;
 }
 
+#if defined(__native_client__)
+void nacl_shutdown_gc_thread(void);
+#endif
+
 /*
  * mono_thread_info_exit:
  *
@@ -1408,28 +1426,66 @@ mono_thread_info_tls_set (THREAD_INFO_TYPE *info, MonoTlsKey key, gpointer value
  * This function doesn't return.
  */
 void
-mono_thread_info_exit (void)
+mono_thread_info_exit (gsize exit_code)
 {
+#if defined(__native_client__)
+       nacl_shutdown_gc_thread();
+#endif
+
+       mono_thread_info_detach ();
+
        mono_threads_platform_exit (0);
 }
 
 /*
  * mono_threads_open_thread_handle:
  *
- *   Return a io-layer/win32 handle for the thread identified by HANDLE/TID.
- * The handle need to be closed by calling CloseHandle () when it is no
- * longer needed.
+ *  Duplicate the handle. The handle needs to be closed by calling
+ *  mono_threads_close_thread_handle () when it is no longer needed.
  */
-HANDLE
-mono_threads_open_thread_handle (HANDLE handle, MonoNativeThreadId tid)
+MonoThreadHandle*
+mono_threads_open_thread_handle (MonoThreadHandle *thread_handle)
 {
-       return mono_threads_platform_open_thread_handle (handle, tid);
+       guint32 oldref, newref;
+
+       g_assert (thread_handle);
+
+       do {
+               oldref = thread_handle->ref;
+               if (!(oldref >= 1))
+                       g_error ("%s: thread_handle %p has ref %u, it should be >= 1", __func__, thread_handle, oldref);
+
+               newref = oldref + 1;
+       } while (InterlockedCompareExchange ((gint32*) &thread_handle->ref, newref, oldref) != oldref);
+
+       return thread_handle;
 }
 
 void
-mono_threads_close_thread_handle (HANDLE handle)
+mono_threads_close_thread_handle (MonoThreadHandle *thread_handle)
+{
+       guint32 oldref, newref;
+
+       g_assert (thread_handle);
+
+       do {
+               oldref = thread_handle->ref;
+               if (!(oldref >= 1))
+                       g_error ("%s: thread_handle %p has ref %u, it should be >= 1", __func__, thread_handle, oldref);
+
+               newref = oldref - 1;
+       } while (InterlockedCompareExchange ((gint32*) &thread_handle->ref, newref, oldref) != oldref);
+
+       if (newref == 0) {
+               mono_os_event_destroy (&thread_handle->event);
+               g_free (thread_handle);
+       }
+}
+
+static void
+mono_threads_signal_thread_handle (MonoThreadHandle* thread_handle)
 {
-       return mono_threads_platform_close_thread_handle (handle);
+       mono_os_event_set (&thread_handle->event);
 }
 
 #define INTERRUPT_STATE ((MonoThreadInfoInterruptToken*) (size_t) -1)
@@ -1638,18 +1694,46 @@ mono_thread_info_is_current (MonoThreadInfo *info)
        return mono_thread_info_get_tid (info) == mono_native_thread_id_get ();
 }
 
-void
-mono_thread_info_set_exited (THREAD_INFO_TYPE *info)
+MonoThreadInfoWaitRet
+mono_thread_info_wait_one_handle (MonoThreadHandle *thread_handle, guint32 timeout, gboolean alertable)
 {
-       g_assert (mono_thread_info_is_current (info));
+       MonoOSEventWaitRet res;
 
-       g_assert (info->handle);
-       mono_threads_platform_set_exited (info->handle);
+       res = mono_os_event_wait_one (&thread_handle->event, timeout);
+       if (res == MONO_OS_EVENT_WAIT_RET_SUCCESS_0)
+               return MONO_THREAD_INFO_WAIT_RET_SUCCESS_0;
+       else if (res == MONO_OS_EVENT_WAIT_RET_ALERTED)
+               return MONO_THREAD_INFO_WAIT_RET_ALERTED;
+       else if (res == MONO_OS_EVENT_WAIT_RET_TIMEOUT)
+               return MONO_THREAD_INFO_WAIT_RET_TIMEOUT;
+       else
+               g_error ("%s: unknown res value %d", __func__, res);
 }
 
-gpointer
-mono_thread_info_duplicate_handle (MonoThreadInfo *info)
+MonoThreadInfoWaitRet
+mono_thread_info_wait_multiple_handle (MonoThreadHandle **thread_handles, gsize nhandles, MonoOSEvent *background_change_event, gboolean waitall, guint32 timeout, gboolean alertable)
 {
-       g_assert (mono_thread_info_is_current (info));
-       return mono_threads_platform_duplicate_handle (info);
+       MonoOSEventWaitRet res;
+       MonoOSEvent *thread_events [MONO_OS_EVENT_WAIT_MAXIMUM_OBJECTS];
+       gint i;
+
+       g_assert (nhandles <= MONO_OS_EVENT_WAIT_MAXIMUM_OBJECTS);
+       if (background_change_event)
+               g_assert (nhandles <= MONO_OS_EVENT_WAIT_MAXIMUM_OBJECTS - 1);
+
+       for (i = 0; i < nhandles; ++i)
+               thread_events [i] = &thread_handles [i]->event;
+
+       if (background_change_event)
+               thread_events [nhandles ++] = background_change_event;
+
+       res = mono_os_event_wait_multiple (thread_events, nhandles, waitall, timeout);
+       if (res >= MONO_OS_EVENT_WAIT_RET_SUCCESS_0 && res <= MONO_OS_EVENT_WAIT_RET_SUCCESS_0 + nhandles - 1)
+               return MONO_THREAD_INFO_WAIT_RET_SUCCESS_0 + (res - MONO_OS_EVENT_WAIT_RET_SUCCESS_0);
+       else if (res == MONO_OS_EVENT_WAIT_RET_ALERTED)
+               return MONO_THREAD_INFO_WAIT_RET_ALERTED;
+       else if (res == MONO_OS_EVENT_WAIT_RET_TIMEOUT)
+               return MONO_THREAD_INFO_WAIT_RET_TIMEOUT;
+       else
+               g_error ("%s: unknown res value %d", __func__, res);
 }
index 90c44c8b74df2cb4081b1cdfd9f7039cc62b6642..a9776c32dbf8dc99a4e47fef09064210cdf23848 100644 (file)
@@ -15,6 +15,7 @@
 #include <mono/utils/mono-linked-list-set.h>
 #include <mono/utils/mono-tls.h>
 #include <mono/utils/mono-coop-semaphore.h>
+#include <mono/utils/os-event.h>
 
 #include <mono/io-layer/io-layer.h>
 
@@ -62,6 +63,11 @@ typedef gsize (*MonoThreadStart)(gpointer);
 
 #endif /* #ifdef HOST_WIN32 */
 
+typedef struct {
+       guint32 ref;
+       MonoOSEvent event;
+} MonoThreadHandle;
+
 /*
 THREAD_INFO_TYPE is a way to make the mono-threads module parametric - or sort of.
 The GC using mono-threads might extend the MonoThreadInfo struct to add its own
@@ -192,7 +198,7 @@ typedef struct {
 
        /* IO layer handle for this thread */
        /* Set when the thread is started, or in _wapi_thread_duplicate () */
-       HANDLE handle;
+       MonoThreadHandle *handle;
 
        void *jit_data;
 
@@ -223,6 +229,7 @@ typedef struct {
        void (*thread_detach)(THREAD_INFO_TYPE *info);
        void (*thread_attach)(THREAD_INFO_TYPE *info);
        gboolean (*mono_method_is_critical) (void *method);
+       gboolean (*ip_in_critical_region) (MonoDomain *domain, gpointer ip);
        gboolean (*mono_thread_in_critical_region) (THREAD_INFO_TYPE *info);
 } MonoThreadInfoCallbacks;
 
@@ -369,10 +376,7 @@ void
 mono_thread_info_tls_set (THREAD_INFO_TYPE *info, MonoTlsKey key, gpointer value);
 
 void
-mono_thread_info_exit (void);
-
-void
-mono_thread_info_set_exited (THREAD_INFO_TYPE *info);
+mono_thread_info_exit (gsize exit_code);
 
 void
 mono_thread_info_install_interrupt (void (*callback) (gpointer data), gpointer data, gboolean *interrupted);
@@ -401,17 +405,17 @@ mono_thread_info_describe_interrupt_token (THREAD_INFO_TYPE *info, GString *text
 gboolean
 mono_thread_info_is_live (THREAD_INFO_TYPE *info);
 
-HANDLE
+MonoThreadHandle*
 mono_threads_create_thread (MonoThreadStart start, gpointer arg, gsize * const stack_size, MonoNativeThreadId *out_tid);
 
 int
 mono_threads_get_max_stack_size (void);
 
-HANDLE
-mono_threads_open_thread_handle (HANDLE handle, MonoNativeThreadId tid);
+MonoThreadHandle*
+mono_threads_open_thread_handle (MonoThreadHandle *handle);
 
 void
-mono_threads_close_thread_handle (HANDLE handle);
+mono_threads_close_thread_handle (MonoThreadHandle *handle);
 
 MONO_API void
 mono_threads_attach_tools_thread (void);
@@ -436,8 +440,6 @@ void mono_threads_suspend_init (void); //ok
 
 void mono_threads_suspend_init_signals (void);
 
-void mono_threads_platform_init (void);
-
 void mono_threads_coop_init (void);
 
 /*
@@ -477,16 +479,10 @@ gint mono_threads_suspend_get_suspend_signal (void);
 gint mono_threads_suspend_get_restart_signal (void);
 gint mono_threads_suspend_get_abort_signal (void);
 
-void mono_threads_platform_register (THREAD_INFO_TYPE *info);
-void mono_threads_platform_unregister (THREAD_INFO_TYPE *info);
 int mono_threads_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_data, gsize* const stack_size, MonoNativeThreadId *out_tid);
 void mono_threads_platform_get_stack_bounds (guint8 **staddr, size_t *stsize);
 gboolean mono_threads_platform_yield (void);
-void mono_threads_platform_exit (int exit_code);
-HANDLE mono_threads_platform_open_thread_handle (HANDLE handle, MonoNativeThreadId tid);
-void mono_threads_platform_close_thread_handle (HANDLE handle);
-void mono_threads_platform_set_exited (gpointer handle);
-gpointer mono_threads_platform_duplicate_handle (THREAD_INFO_TYPE *info);
+void mono_threads_platform_exit (gsize exit_code);
 
 void mono_threads_coop_begin_global_suspend (void);
 void mono_threads_coop_end_global_suspend (void);
@@ -604,7 +600,17 @@ void mono_threads_end_global_suspend (void);
 gboolean
 mono_thread_info_is_current (THREAD_INFO_TYPE *info);
 
-gpointer
-mono_thread_info_duplicate_handle (THREAD_INFO_TYPE *info);
+typedef enum {
+       MONO_THREAD_INFO_WAIT_RET_SUCCESS_0   =  0,
+       MONO_THREAD_INFO_WAIT_RET_ALERTED     = -1,
+       MONO_THREAD_INFO_WAIT_RET_TIMEOUT     = -2,
+       MONO_THREAD_INFO_WAIT_RET_FAILED      = -3,
+} MonoThreadInfoWaitRet;
+
+MonoThreadInfoWaitRet
+mono_thread_info_wait_one_handle (MonoThreadHandle *handle, guint32 timeout, gboolean alertable);
+
+MonoThreadInfoWaitRet
+mono_thread_info_wait_multiple_handle (MonoThreadHandle **thread_handles, gsize nhandles, MonoOSEvent *background_change_event, gboolean waitall, guint32 timeout, gboolean alertable);
 
 #endif /* __MONO_THREADS_H__ */
index 12ef05c26978b023e3fee21fe8b40be76bbafa4e..a2678b4f949180c4530bc4a6bab5e009e4b8aad1 100644 (file)
@@ -80,10 +80,10 @@ mono_os_event_set (MonoOSEvent *event)
        mono_os_mutex_lock (&event->mutex);
 
        if (event->manual) {
-               mono_os_event_signal (event, FALSE);
+               mono_os_event_signal (event, TRUE);
        } else {
                event->set_count = 1;
-               mono_os_event_signal (event, TRUE);
+               mono_os_event_signal (event, FALSE);
        }
 
        mono_os_mutex_unlock (&event->mutex);
diff --git a/mono/utils/w32handle.c b/mono/utils/w32handle.c
deleted file mode 100644 (file)
index bd82fb5..0000000
+++ /dev/null
@@ -1,1546 +0,0 @@
-/*
- * w32handle.c:  Generic and internal operations on handles
- *
- * Author:
- *     Dick Porter (dick@ximian.com)
- *     Ludovic Henry (luhenry@microsoft.com)
- *
- * (C) 2002-2011 Novell, Inc.
- * Copyright 2011 Xamarin Inc
- * Licensed under the MIT license. See LICENSE file in the project root for full license information.
- */
-
-#include <config.h>
-
-#if !defined(HOST_WIN32)
-
-#include <glib.h>
-#include <pthread.h>
-#include <errno.h>
-#include <unistd.h>
-#ifdef HAVE_SIGNAL_H
-#include <signal.h>
-#endif
-#include <string.h>
-#include <sys/types.h>
-#ifdef HAVE_SYS_SOCKET_H
-#  include <sys/socket.h>
-#endif
-#ifdef HAVE_SYS_UN_H
-#  include <sys/un.h>
-#endif
-#ifdef HAVE_SYS_MMAN_H
-#  include <sys/mman.h>
-#endif
-#ifdef HAVE_DIRENT_H
-#  include <dirent.h>
-#endif
-#include <sys/stat.h>
-#ifdef HAVE_SYS_RESOURCE_H
-#  include <sys/resource.h>
-#endif
-
-#include "w32handle.h"
-
-#include "atomic.h"
-#include "mono-logger-internals.h"
-#include "mono-os-mutex.h"
-#include "mono-proclib.h"
-#include "mono-threads.h"
-#include "mono-time.h"
-
-#undef DEBUG_REFS
-
-#define SLOT_MAX               (1024 * 16)
-
-/* must be a power of 2 */
-#define HANDLE_PER_SLOT        (256)
-
-#define INFINITE 0xFFFFFFFF
-
-typedef struct {
-       MonoW32HandleType type;
-       guint ref;
-       gboolean signalled;
-       mono_mutex_t signal_mutex;
-       mono_cond_t signal_cond;
-       gpointer specific;
-} MonoW32HandleBase;
-
-static MonoW32HandleCapability handle_caps [MONO_W32HANDLE_COUNT];
-static MonoW32HandleOps *handle_ops [MONO_W32HANDLE_COUNT];
-
-/*
- * We can hold SLOT_MAX * HANDLE_PER_SLOT handles.
- * If 4M handles are not enough... Oh, well... we will crash.
- */
-#define SLOT_INDEX(x)  (x / HANDLE_PER_SLOT)
-#define SLOT_OFFSET(x) (x % HANDLE_PER_SLOT)
-
-static MonoW32HandleBase *private_handles [SLOT_MAX];
-static guint32 private_handles_count = 0;
-static guint32 private_handles_slots_count = 0;
-
-guint32 mono_w32handle_fd_reserve;
-
-/*
- * This is an internal handle which is used for handling waiting for multiple handles.
- * Threads which wait for multiple handles wait on this one handle, and when a handle
- * is signalled, this handle is signalled too.
- */
-static mono_mutex_t global_signal_mutex;
-static mono_cond_t global_signal_cond;
-
-static mono_mutex_t scan_mutex;
-
-static gboolean shutting_down = FALSE;
-
-static gboolean
-type_is_fd (MonoW32HandleType type)
-{
-       switch (type) {
-       case MONO_W32HANDLE_FILE:
-       case MONO_W32HANDLE_CONSOLE:
-       case MONO_W32HANDLE_SOCKET:
-       case MONO_W32HANDLE_PIPE:
-               return TRUE;
-       default:
-               return FALSE;
-       }
-}
-
-static gboolean
-mono_w32handle_lookup_data (gpointer handle, MonoW32HandleBase **handle_data)
-{
-       gsize index, offset;
-
-       g_assert (handle_data);
-
-       index = SLOT_INDEX ((gsize) handle);
-       if (index >= SLOT_MAX)
-               return FALSE;
-       if (!private_handles [index])
-               return FALSE;
-
-       offset = SLOT_OFFSET ((gsize) handle);
-       if (private_handles [index][offset].type == MONO_W32HANDLE_UNUSED)
-               return FALSE;
-
-       *handle_data = &private_handles [index][offset];
-       return TRUE;
-}
-
-MonoW32HandleType
-mono_w32handle_get_type (gpointer handle)
-{
-       MonoW32HandleBase *handle_data;
-
-       if (!mono_w32handle_lookup_data (handle, &handle_data))
-               return MONO_W32HANDLE_UNUSED;   /* An impossible type */
-
-       return handle_data->type;
-}
-
-void
-mono_w32handle_set_signal_state (gpointer handle, gboolean state, gboolean broadcast)
-{
-       MonoW32HandleBase *handle_data;
-
-       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
-               return;
-       }
-
-#ifdef DEBUG
-       g_message ("%s: setting state of %p to %s (broadcast %s)", __func__,
-                  handle, state?"TRUE":"FALSE", broadcast?"TRUE":"FALSE");
-#endif
-
-       if (state == TRUE) {
-               /* Tell everyone blocking on a single handle */
-
-               /* The condition the global signal cond is waiting on is the signalling of
-                * _any_ handle. So lock it before setting the signalled state.
-                */
-               mono_os_mutex_lock (&global_signal_mutex);
-
-               /* This function _must_ be called with
-                * handle->signal_mutex locked
-                */
-               handle_data->signalled=state;
-
-               if (broadcast == TRUE) {
-                       mono_os_cond_broadcast (&handle_data->signal_cond);
-               } else {
-                       mono_os_cond_signal (&handle_data->signal_cond);
-               }
-
-               /* Tell everyone blocking on multiple handles that something
-                * was signalled
-                */
-               mono_os_cond_broadcast (&global_signal_cond);
-
-               mono_os_mutex_unlock (&global_signal_mutex);
-       } else {
-               handle_data->signalled=state;
-       }
-}
-
-gboolean
-mono_w32handle_issignalled (gpointer handle)
-{
-       MonoW32HandleBase *handle_data;
-
-       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
-               return(FALSE);
-       }
-
-       return handle_data->signalled;
-}
-
-static int
-mono_w32handle_lock_signal_mutex (void)
-{
-#ifdef DEBUG
-       g_message ("%s: lock global signal mutex", __func__);
-#endif
-
-       mono_os_mutex_lock (&global_signal_mutex);
-
-       return 0;
-}
-
-static int
-mono_w32handle_unlock_signal_mutex (void)
-{
-#ifdef DEBUG
-       g_message ("%s: unlock global signal mutex", __func__);
-#endif
-
-       mono_os_mutex_unlock (&global_signal_mutex);
-
-       return 0;
-}
-
-int
-mono_w32handle_lock_handle (gpointer handle)
-{
-       MonoW32HandleBase *handle_data;
-
-#ifdef DEBUG
-       g_message ("%s: locking handle %p", __func__, handle);
-#endif
-
-       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
-               return(0);
-       }
-
-       mono_w32handle_ref (handle);
-
-       mono_os_mutex_lock (&handle_data->signal_mutex);
-
-       return 0;
-}
-
-int
-mono_w32handle_trylock_handle (gpointer handle)
-{
-       MonoW32HandleBase *handle_data;
-       int ret;
-
-#ifdef DEBUG
-       g_message ("%s: locking handle %p", __func__, handle);
-#endif
-
-       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
-               return(0);
-       }
-
-       mono_w32handle_ref (handle);
-
-       ret = mono_os_mutex_trylock (&handle_data->signal_mutex);
-       if (ret != 0) {
-               mono_w32handle_unref (handle);
-       }
-
-       return(ret);
-}
-
-int
-mono_w32handle_unlock_handle (gpointer handle)
-{
-       MonoW32HandleBase *handle_data;
-
-#ifdef DEBUG
-       g_message ("%s: unlocking handle %p", __func__, handle);
-#endif
-
-       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
-               return(0);
-       }
-
-       mono_os_mutex_unlock (&handle_data->signal_mutex);
-
-       mono_w32handle_unref (handle);
-
-       return 0;
-}
-
-/*
- * wapi_init:
- *
- *   Initialize the io-layer.
- */
-void
-mono_w32handle_init (void)
-{
-       static gboolean initialized = FALSE;
-
-       if (initialized)
-               return;
-
-       g_assert ((sizeof (handle_ops) / sizeof (handle_ops[0]))
-                 == MONO_W32HANDLE_COUNT);
-
-       /* This is needed by the code in mono_w32handle_new_internal */
-       mono_w32handle_fd_reserve = (eg_getdtablesize () + (HANDLE_PER_SLOT - 1)) & ~(HANDLE_PER_SLOT - 1);
-
-       do {
-               /*
-                * The entries in private_handles reserved for fds are allocated lazily to
-                * save memory.
-                */
-
-               private_handles_count += HANDLE_PER_SLOT;
-               private_handles_slots_count ++;
-       } while(mono_w32handle_fd_reserve > private_handles_count);
-
-       mono_os_mutex_init (&scan_mutex);
-
-       mono_os_cond_init (&global_signal_cond);
-       mono_os_mutex_init (&global_signal_mutex);
-
-       initialized = TRUE;
-}
-
-void
-mono_w32handle_cleanup (void)
-{
-       int i, j, k;
-
-       g_assert (!shutting_down);
-       shutting_down = TRUE;
-
-       /* Every shared handle we were using ought really to be closed
-        * by now, but to make sure just blow them all away.  The
-        * exiting finalizer thread in particular races us to the
-        * program exit and doesn't always win, so it can be left
-        * cluttering up the shared file.  Anything else left over is
-        * really a bug.
-        */
-       for(i = SLOT_INDEX (0); private_handles[i] != NULL; i++) {
-               for(j = SLOT_OFFSET (0); j < HANDLE_PER_SLOT; j++) {
-                       MonoW32HandleBase *handle_data = &private_handles[i][j];
-                       gpointer handle = GINT_TO_POINTER (i*HANDLE_PER_SLOT+j);
-
-                       for(k = handle_data->ref; k > 0; k--) {
-                               mono_w32handle_unref (handle);
-                       }
-               }
-       }
-
-       for (i = 0; i < SLOT_MAX; ++i)
-               g_free (private_handles [i]);
-}
-
-static void mono_w32handle_init_handle (MonoW32HandleBase *handle,
-                              MonoW32HandleType type, gpointer handle_specific)
-{
-       g_assert (handle->ref == 0);
-
-       handle->type = type;
-       handle->signalled = FALSE;
-       handle->ref = 1;
-
-       mono_os_cond_init (&handle->signal_cond);
-       mono_os_mutex_init (&handle->signal_mutex);
-
-       if (handle_specific)
-               handle->specific = g_memdup (handle_specific, mono_w32handle_ops_typesize (type));
-}
-
-/*
- * mono_w32handle_new_internal:
- * @type: Init handle to this type
- *
- * Search for a free handle and initialize it. Return the handle on
- * success and 0 on failure.  This is only called from
- * mono_w32handle_new, and scan_mutex must be held.
- */
-static guint32 mono_w32handle_new_internal (MonoW32HandleType type,
-                                         gpointer handle_specific)
-{
-       guint32 i, k, count;
-       static guint32 last = 0;
-       gboolean retry = FALSE;
-       
-       /* A linear scan should be fast enough.  Start from the last
-        * allocation, assuming that handles are allocated more often
-        * than they're freed. Leave the space reserved for file
-        * descriptors
-        */
-
-       if (last < mono_w32handle_fd_reserve) {
-               last = mono_w32handle_fd_reserve;
-       } else {
-               retry = TRUE;
-       }
-
-again:
-       count = last;
-       for(i = SLOT_INDEX (count); i < private_handles_slots_count; i++) {
-               if (private_handles [i]) {
-                       for (k = SLOT_OFFSET (count); k < HANDLE_PER_SLOT; k++) {
-                               MonoW32HandleBase *handle = &private_handles [i][k];
-
-                               if(handle->type == MONO_W32HANDLE_UNUSED) {
-                                       last = count + 1;
-
-                                       mono_w32handle_init_handle (handle, type, handle_specific);
-                                       return (count);
-                               }
-                               count++;
-                       }
-               }
-       }
-
-       if(retry && last > mono_w32handle_fd_reserve) {
-               /* Try again from the beginning */
-               last = mono_w32handle_fd_reserve;
-               goto again;
-       }
-
-       /* Will need to expand the array.  The caller will sort it out */
-
-       return(0);
-}
-
-gpointer
-mono_w32handle_new (MonoW32HandleType type, gpointer handle_specific)
-{
-       guint32 handle_idx = 0;
-       gpointer handle;
-
-       g_assert (!shutting_down);
-
-       g_assert(!type_is_fd(type));
-
-       mono_os_mutex_lock (&scan_mutex);
-
-       while ((handle_idx = mono_w32handle_new_internal (type, handle_specific)) == 0) {
-               /* Try and expand the array, and have another go */
-               int idx = SLOT_INDEX (private_handles_count);
-               if (idx >= SLOT_MAX) {
-                       break;
-               }
-
-               private_handles [idx] = g_new0 (MonoW32HandleBase, HANDLE_PER_SLOT);
-
-               private_handles_count += HANDLE_PER_SLOT;
-               private_handles_slots_count ++;
-       }
-
-       mono_os_mutex_unlock (&scan_mutex);
-
-       if (handle_idx == 0) {
-               /* We ran out of slots */
-               handle = INVALID_HANDLE_VALUE;
-               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: failed to create %s handle", __func__, mono_w32handle_ops_typename (type));
-               goto done;
-       }
-
-       /* Make sure we left the space for fd mappings */
-       g_assert (handle_idx >= mono_w32handle_fd_reserve);
-
-       handle = GUINT_TO_POINTER (handle_idx);
-
-       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: create %s handle %p", __func__, mono_w32handle_ops_typename (type), handle);
-
-done:
-       return(handle);
-}
-
-gpointer mono_w32handle_new_fd (MonoW32HandleType type, int fd,
-                             gpointer handle_specific)
-{
-       MonoW32HandleBase *handle_data;
-       int fd_index, fd_offset;
-
-       g_assert (!shutting_down);
-
-       g_assert(type_is_fd(type));
-
-       if (fd >= mono_w32handle_fd_reserve) {
-               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: failed to create %s handle, fd is too big", __func__, mono_w32handle_ops_typename (type));
-
-               return(GUINT_TO_POINTER (INVALID_HANDLE_VALUE));
-       }
-
-       fd_index = SLOT_INDEX (fd);
-       fd_offset = SLOT_OFFSET (fd);
-
-       /* Initialize the array entries on demand */
-       if (!private_handles [fd_index]) {
-               mono_os_mutex_lock (&scan_mutex);
-
-               if (!private_handles [fd_index])
-                       private_handles [fd_index] = g_new0 (MonoW32HandleBase, HANDLE_PER_SLOT);
-
-               mono_os_mutex_unlock (&scan_mutex);
-       }
-
-       handle_data = &private_handles [fd_index][fd_offset];
-
-       if (handle_data->type != MONO_W32HANDLE_UNUSED) {
-               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: failed to create %s handle, fd is already in use", __func__, mono_w32handle_ops_typename (type));
-               /* FIXME: clean up this handle?  We can't do anything
-                * with the fd, cos thats the new one
-                */
-               return(GUINT_TO_POINTER (INVALID_HANDLE_VALUE));
-       }
-
-       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: create %s handle %p", __func__, mono_w32handle_ops_typename (type), GUINT_TO_POINTER(fd));
-
-       mono_w32handle_init_handle (handle_data, type, handle_specific);
-
-       return(GUINT_TO_POINTER(fd));
-}
-
-gboolean
-mono_w32handle_lookup (gpointer handle, MonoW32HandleType type,
-                             gpointer *handle_specific)
-{
-       MonoW32HandleBase *handle_data;
-
-       g_assert (handle_specific);
-
-       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
-               return(FALSE);
-       }
-
-       if (handle_data->type != type) {
-               return(FALSE);
-       }
-
-       *handle_specific = handle_data->specific;
-
-       return(TRUE);
-}
-
-static gboolean
-mono_w32handle_ref_core (gpointer handle, MonoW32HandleBase *handle_data);
-
-static gboolean
-mono_w32handle_unref_core (gpointer handle, MonoW32HandleBase *handle_data, guint minimum);
-
-void
-mono_w32handle_foreach (gboolean (*on_each)(gpointer handle, gpointer data, gpointer user_data), gpointer user_data)
-{
-       guint32 i, k;
-
-       mono_os_mutex_lock (&scan_mutex);
-
-       for (i = SLOT_INDEX (0); i < private_handles_slots_count; i++) {
-               if (!private_handles [i])
-                       continue;
-               for (k = SLOT_OFFSET (0); k < HANDLE_PER_SLOT; k++) {
-                       MonoW32HandleBase *handle_data = NULL;
-                       gpointer handle;
-                       gboolean destroy, finished;
-
-                       handle_data = &private_handles [i][k];
-                       if (handle_data->type == MONO_W32HANDLE_UNUSED)
-                               continue;
-
-                       handle = GUINT_TO_POINTER (i * HANDLE_PER_SLOT + k);
-
-                       if (!mono_w32handle_ref_core (handle, handle_data)) {
-                               /* we are racing with mono_w32handle_unref:
-                                *  the handle ref has been decremented, but it
-                                *  hasn't yet been destroyed. */
-                               continue;
-                       }
-
-                       finished = on_each (handle, handle_data->specific, user_data);
-
-                       /* we do not want to have to destroy the handle here,
-                        * as it would means the ref/unref are unbalanced */
-                       destroy = mono_w32handle_unref_core (handle, handle_data, 2);
-                       g_assert (!destroy);
-
-                       if (finished)
-                               goto done;
-               }
-       }
-
-done:
-       mono_os_mutex_unlock (&scan_mutex);
-}
-
-typedef struct {
-       MonoW32HandleType type;
-       gboolean (*search_user_callback)(gpointer handle, gpointer data);
-       gpointer search_user_data;
-       gpointer handle;
-       gpointer handle_specific;
-} SearchData;
-
-static gboolean
-search_callback (gpointer handle, gpointer handle_specific, gpointer user_data)
-{
-       SearchData *search_data = (SearchData*) user_data;
-
-       if (search_data->type != mono_w32handle_get_type (handle))
-               return FALSE;
-
-       if (!search_data->search_user_callback (handle, search_data->search_user_data))
-               return FALSE;
-
-       mono_w32handle_ref (handle);
-       search_data->handle = handle;
-       search_data->handle_specific = handle_specific;
-       return TRUE;
-}
-
-/* This might list some shared handles twice if they are already
- * opened by this process, and the check function returns FALSE the
- * first time.  Shared handles that are created during the search are
- * unreffed if the check function returns FALSE, so callers must not
- * rely on the handle persisting (unless the check function returns
- * TRUE)
- * The caller owns the returned handle.
- */
-gpointer mono_w32handle_search (MonoW32HandleType type,
-                             gboolean (*check)(gpointer test, gpointer user),
-                             gpointer user_data,
-                             gpointer *handle_specific,
-                             gboolean search_shared)
-{
-       SearchData search_data;
-
-       memset (&search_data, 0, sizeof (search_data));
-       search_data.type = type;
-       search_data.search_user_callback = check;
-       search_data.search_user_data = user_data;
-       mono_w32handle_foreach (search_callback, &search_data);
-       if (handle_specific)
-               *handle_specific = search_data.handle_specific;
-       return search_data.handle;
-}
-
-static gboolean
-mono_w32handle_ref_core (gpointer handle, MonoW32HandleBase *handle_data)
-{
-       guint old, new;
-
-       do {
-               old = handle_data->ref;
-               if (old == 0)
-                       return FALSE;
-
-               new = old + 1;
-       } while (InterlockedCompareExchange ((gint32*) &handle_data->ref, new, old) != old);
-
-       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: ref %s handle %p, ref: %d -> %d",
-               __func__, mono_w32handle_ops_typename (handle_data->type), handle, old, new);
-
-       return TRUE;
-}
-
-static gboolean
-mono_w32handle_unref_core (gpointer handle, MonoW32HandleBase *handle_data, guint minimum)
-{
-       MonoW32HandleType type;
-       guint old, new;
-
-       type = handle_data->type;
-
-       do {
-               old = handle_data->ref;
-               if (!(old >= minimum))
-                       g_error ("%s: handle %p has ref %d, it should be >= %d", __func__, handle, old, minimum);
-
-               new = old - 1;
-       } while (InterlockedCompareExchange ((gint32*) &handle_data->ref, new, old) != old);
-
-       /* handle_data might contain invalid data from now on, if
-        * another thread is unref'ing this handle at the same time */
-
-       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: unref %s handle %p, ref: %d -> %d destroy: %s",
-               __func__, mono_w32handle_ops_typename (type), handle, old, new, new == 0 ? "true" : "false");
-
-       return new == 0;
-}
-
-void mono_w32handle_ref (gpointer handle)
-{
-       MonoW32HandleBase *handle_data;
-
-       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
-               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: failed to ref handle %p, unknown handle", __func__, handle);
-               return;
-       }
-
-       if (!mono_w32handle_ref_core (handle, handle_data))
-               g_error ("%s: failed to ref handle %p", __func__, handle);
-}
-
-static void (*_wapi_handle_ops_get_close_func (MonoW32HandleType type))(gpointer, gpointer);
-
-/* The handle must not be locked on entry to this function */
-void
-mono_w32handle_unref (gpointer handle)
-{
-       MonoW32HandleBase *handle_data;
-       gboolean destroy;
-
-       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
-               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: failed to unref handle %p, unknown handle",
-                       __func__, handle);
-               return;
-       }
-
-       destroy = mono_w32handle_unref_core (handle, handle_data, 1);
-
-       if (destroy) {
-               /* Need to copy the handle info, reset the slot in the
-                * array, and _only then_ call the close function to
-                * avoid race conditions (eg file descriptors being
-                * closed, and another file being opened getting the
-                * same fd racing the memset())
-                */
-               MonoW32HandleType type;
-               gpointer handle_specific;
-               void (*close_func)(gpointer, gpointer);
-
-               type = handle_data->type;
-               handle_specific = handle_data->specific;
-
-               mono_os_mutex_lock (&scan_mutex);
-
-               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: destroy %s handle %p", __func__, mono_w32handle_ops_typename (type), handle);
-
-               mono_os_mutex_destroy (&handle_data->signal_mutex);
-               mono_os_cond_destroy (&handle_data->signal_cond);
-
-               memset (handle_data, 0, sizeof (MonoW32HandleBase));
-
-               mono_os_mutex_unlock (&scan_mutex);
-
-               close_func = _wapi_handle_ops_get_close_func (type);
-               if (close_func != NULL) {
-                       close_func (handle, handle_specific);
-               }
-
-               g_free (handle_specific);
-       }
-}
-
-void
-mono_w32handle_register_ops (MonoW32HandleType type, MonoW32HandleOps *ops)
-{
-       handle_ops [type] = ops;
-}
-
-void mono_w32handle_register_capabilities (MonoW32HandleType type,
-                                        MonoW32HandleCapability caps)
-{
-       handle_caps[type] = caps;
-}
-
-gboolean mono_w32handle_test_capabilities (gpointer handle,
-                                        MonoW32HandleCapability caps)
-{
-       MonoW32HandleBase *handle_data;
-       MonoW32HandleType type;
-
-       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
-               return(FALSE);
-       }
-
-       type = handle_data->type;
-
-       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: testing 0x%x against 0x%x (%d)", __func__,
-                  handle_caps[type], caps, handle_caps[type] & caps);
-
-       return((handle_caps[type] & caps) != 0);
-}
-
-static void (*_wapi_handle_ops_get_close_func (MonoW32HandleType type))(gpointer, gpointer)
-{
-       if (handle_ops[type] != NULL &&
-           handle_ops[type]->close != NULL) {
-               return (handle_ops[type]->close);
-       }
-
-       return (NULL);
-}
-
-void mono_w32handle_ops_close (gpointer handle, gpointer data)
-{
-       MonoW32HandleBase *handle_data;
-       MonoW32HandleType type;
-
-       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
-               return;
-       }
-
-       type = handle_data->type;
-
-       if (handle_ops[type] != NULL &&
-           handle_ops[type]->close != NULL) {
-               handle_ops[type]->close (handle, data);
-       }
-}
-
-void mono_w32handle_ops_details (MonoW32HandleType type, gpointer data)
-{
-       if (handle_ops[type] != NULL &&
-           handle_ops[type]->details != NULL) {
-               handle_ops[type]->details (data);
-       }
-}
-
-const gchar* mono_w32handle_ops_typename (MonoW32HandleType type)
-{
-       g_assert (handle_ops [type]);
-       g_assert (handle_ops [type]->typename);
-       return handle_ops [type]->typename ();
-}
-
-gsize mono_w32handle_ops_typesize (MonoW32HandleType type)
-{
-       g_assert (handle_ops [type]);
-       g_assert (handle_ops [type]->typesize);
-       return handle_ops [type]->typesize ();
-}
-
-void mono_w32handle_ops_signal (gpointer handle)
-{
-       MonoW32HandleBase *handle_data;
-       MonoW32HandleType type;
-
-       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
-               return;
-       }
-
-       type = handle_data->type;
-
-       if (handle_ops[type] != NULL && handle_ops[type]->signal != NULL) {
-               handle_ops[type]->signal (handle);
-       }
-}
-
-gboolean mono_w32handle_ops_own (gpointer handle, guint32 *statuscode)
-{
-       MonoW32HandleBase *handle_data;
-       MonoW32HandleType type;
-
-       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
-               return(FALSE);
-       }
-
-       type = handle_data->type;
-
-       if (handle_ops[type] != NULL && handle_ops[type]->own_handle != NULL) {
-               return(handle_ops[type]->own_handle (handle, statuscode));
-       } else {
-               return(FALSE);
-       }
-}
-
-gboolean mono_w32handle_ops_isowned (gpointer handle)
-{
-       MonoW32HandleBase *handle_data;
-       MonoW32HandleType type;
-
-       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
-               return(FALSE);
-       }
-
-       type = handle_data->type;
-
-       if (handle_ops[type] != NULL && handle_ops[type]->is_owned != NULL) {
-               return(handle_ops[type]->is_owned (handle));
-       } else {
-               return(FALSE);
-       }
-}
-
-guint32 mono_w32handle_ops_specialwait (gpointer handle, guint32 timeout, gboolean *alerted)
-{
-       MonoW32HandleBase *handle_data;
-       MonoW32HandleType type;
-
-       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
-               return(WAIT_FAILED);
-       }
-
-       type = handle_data->type;
-
-       if (handle_ops[type] != NULL &&
-           handle_ops[type]->special_wait != NULL) {
-               return(handle_ops[type]->special_wait (handle, timeout, alerted));
-       } else {
-               return(WAIT_FAILED);
-       }
-}
-
-void mono_w32handle_ops_prewait (gpointer handle)
-{
-       MonoW32HandleBase *handle_data;
-       MonoW32HandleType type;
-
-       if (!mono_w32handle_lookup_data (handle, &handle_data)) {
-               return;
-       }
-
-       type = handle_data->type;
-
-       if (handle_ops[type] != NULL &&
-           handle_ops[type]->prewait != NULL) {
-               handle_ops[type]->prewait (handle);
-       }
-}
-
-static void
-spin (guint32 ms)
-{
-       struct timespec sleepytime;
-
-       g_assert (ms < 1000);
-
-       sleepytime.tv_sec = 0;
-       sleepytime.tv_nsec = ms * 1000000;
-       nanosleep (&sleepytime, NULL);
-}
-
-static void
-mono_w32handle_lock_handles (gpointer *handles, gsize numhandles)
-{
-       guint32 i, iter=0;
-       int thr_ret;
-
-       /* Lock all the handles, with backoff */
-again:
-       for(i=0; i<numhandles; i++) {
-               gpointer handle = handles[i];
-
-               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: attempting to lock %p", __func__, handle);
-
-               thr_ret = mono_w32handle_trylock_handle (handle);
-
-               if (thr_ret != 0) {
-                       /* Bummer */
-
-                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: attempt failed for %p: %s", __func__,
-                                  handle, strerror (thr_ret));
-
-                       while (i--) {
-                               handle = handles[i];
-
-                               thr_ret = mono_w32handle_unlock_handle (handle);
-                               g_assert (thr_ret == 0);
-                       }
-
-                       /* If iter ever reaches 100 the nanosleep will
-                        * return EINVAL immediately, but we have a
-                        * design flaw if that happens.
-                        */
-                       iter++;
-                       if(iter==100) {
-                               g_warning ("%s: iteration overflow!",
-                                          __func__);
-                               iter=1;
-                       }
-
-                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Backing off for %d ms", __func__,
-                                  iter*10);
-                       spin (10 * iter);
-
-                       goto again;
-               }
-       }
-
-       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Locked all handles", __func__);
-}
-
-static void
-mono_w32handle_unlock_handles (gpointer *handles, gsize numhandles)
-{
-       guint32 i;
-       int thr_ret;
-
-       for(i=0; i<numhandles; i++) {
-               gpointer handle = handles[i];
-
-               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: unlocking handle %p", __func__, handle);
-
-               thr_ret = mono_w32handle_unlock_handle (handle);
-               g_assert (thr_ret == 0);
-       }
-}
-
-static int
-mono_w32handle_timedwait_signal_naked (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout, gboolean poll, gboolean *alerted)
-{
-       int res;
-
-       if (!poll) {
-               res = mono_os_cond_timedwait (cond, mutex, timeout);
-       } else {
-               /* This is needed when waiting for process handles */
-               if (!alerted) {
-                       /*
-                        * pthread_cond_(timed)wait() can return 0 even if the condition was not
-                        * signalled.  This happens at least on Darwin.  We surface this, i.e., we
-                        * get spurious wake-ups.
-                        *
-                        * http://pubs.opengroup.org/onlinepubs/007908775/xsh/pthread_cond_wait.html
-                        */
-                       res = mono_os_cond_timedwait (cond, mutex, timeout);
-               } else {
-                       if (timeout < 100) {
-                               /* Real timeout is less than 100ms time */
-                               res = mono_os_cond_timedwait (cond, mutex, timeout);
-                       } else {
-                               res = mono_os_cond_timedwait (cond, mutex, 100);
-
-                               /* Mask the fake timeout, this will cause
-                                * another poll if the cond was not really signaled
-                                */
-                               if (res == -1)
-                                       res = 0;
-                       }
-               }
-       }
-
-       return res;
-}
-
-static void
-signal_global (gpointer unused)
-{
-       /* If we reach here, then interrupt token is set to the flag value, which
-        * means that the target thread is either
-        * - before the first CAS in timedwait, which means it won't enter the wait.
-        * - it is after the first CAS, so it is already waiting, or it will enter
-        *    the wait, and it will be interrupted by the broadcast. */
-       mono_os_mutex_lock (&global_signal_mutex);
-       mono_os_cond_broadcast (&global_signal_cond);
-       mono_os_mutex_unlock (&global_signal_mutex);
-}
-
-static int
-mono_w32handle_timedwait_signal (guint32 timeout, gboolean poll, gboolean *alerted)
-{
-       int res;
-
-       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: waiting for global", __func__);
-
-       if (alerted)
-               *alerted = FALSE;
-
-       if (alerted) {
-               mono_thread_info_install_interrupt (signal_global, NULL, alerted);
-               if (*alerted)
-                       return 0;
-       }
-
-       res = mono_w32handle_timedwait_signal_naked (&global_signal_cond, &global_signal_mutex, timeout, poll, alerted);
-
-       if (alerted)
-               mono_thread_info_uninstall_interrupt (alerted);
-
-       return res;
-}
-
-static void
-signal_handle_and_unref (gpointer handle)
-{
-       MonoW32HandleBase *handle_data;
-       mono_cond_t *cond;
-       mono_mutex_t *mutex;
-
-       if (!mono_w32handle_lookup_data (handle, &handle_data))
-               g_error ("cannot signal unknown handle %p", handle);
-
-       /* If we reach here, then interrupt token is set to the flag value, which
-        * means that the target thread is either
-        * - before the first CAS in timedwait, which means it won't enter the wait.
-        * - it is after the first CAS, so it is already waiting, or it will enter
-        *    the wait, and it will be interrupted by the broadcast. */
-       cond = &handle_data->signal_cond;
-       mutex = &handle_data->signal_mutex;
-
-       mono_os_mutex_lock (mutex);
-       mono_os_cond_broadcast (cond);
-       mono_os_mutex_unlock (mutex);
-
-       mono_w32handle_unref (handle);
-}
-
-static int
-mono_w32handle_timedwait_signal_handle (gpointer handle, guint32 timeout, gboolean poll, gboolean *alerted)
-{
-       MonoW32HandleBase *handle_data;
-       int res;
-
-       if (!mono_w32handle_lookup_data (handle, &handle_data))
-               g_error ("cannot wait on unknown handle %p", handle);
-
-       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: waiting for %p (type %s)", __func__, handle,
-                  mono_w32handle_ops_typename (mono_w32handle_get_type (handle)));
-
-       if (alerted)
-               *alerted = FALSE;
-
-       if (alerted) {
-               mono_thread_info_install_interrupt (signal_handle_and_unref, handle, alerted);
-               if (*alerted)
-                       return 0;
-               mono_w32handle_ref (handle);
-       }
-
-       res = mono_w32handle_timedwait_signal_naked (&handle_data->signal_cond, &handle_data->signal_mutex, timeout, poll, alerted);
-
-       if (alerted) {
-               mono_thread_info_uninstall_interrupt (alerted);
-               if (!*alerted) {
-                       /* if it is alerted, then the handle is unref in the interrupt callback */
-                       mono_w32handle_unref (handle);
-               }
-       }
-
-       return res;
-}
-
-static gboolean
-dump_callback (gpointer handle, gpointer handle_specific, gpointer user_data)
-{
-       MonoW32HandleBase *handle_data;
-
-       if (!mono_w32handle_lookup_data (handle, &handle_data))
-               g_error ("cannot dump unknown handle %p", handle);
-
-       g_print ("%p [%7s] signalled: %5s ref: %3d ",
-               handle, mono_w32handle_ops_typename (handle_data->type), handle_data->signalled ? "true" : "false", handle_data->ref);
-       mono_w32handle_ops_details (handle_data->type, handle_data->specific);
-       g_print ("\n");
-
-       return FALSE;
-}
-
-void mono_w32handle_dump (void)
-{
-       mono_w32handle_foreach (dump_callback, NULL);
-}
-
-static gboolean
-own_if_signalled (gpointer handle, guint32 *statuscode)
-{
-       if (!mono_w32handle_issignalled (handle))
-               return FALSE;
-
-       *statuscode = WAIT_OBJECT_0;
-       mono_w32handle_ops_own (handle, statuscode);
-       return TRUE;
-}
-
-static gboolean
-own_if_owned( gpointer handle, guint32 *statuscode)
-{
-       if (!mono_w32handle_ops_isowned (handle))
-               return FALSE;
-
-       *statuscode = WAIT_OBJECT_0;
-       mono_w32handle_ops_own (handle, statuscode);
-       return TRUE;
-}
-
-MonoW32HandleWaitRet
-mono_w32handle_wait_one (gpointer handle, guint32 timeout, gboolean alertable)
-{
-       MonoW32HandleWaitRet ret;
-       gboolean alerted;
-       gint64 start;
-       gint thr_ret;
-       guint32 statuscode = 0;
-
-       alerted = FALSE;
-
-       if (mono_w32handle_test_capabilities (handle, MONO_W32HANDLE_CAP_SPECIAL_WAIT)) {
-               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p has special wait",
-                       __func__, handle);
-
-               switch (mono_w32handle_ops_specialwait (handle, timeout, alertable ? &alerted : NULL)) {
-               case WAIT_OBJECT_0:
-                       ret = MONO_W32HANDLE_WAIT_RET_SUCCESS_0;
-                       break;
-               case WAIT_ABANDONED_0:
-                       ret = MONO_W32HANDLE_WAIT_RET_ABANDONED_0;
-                       break;
-               case WAIT_IO_COMPLETION:
-                       ret = MONO_W32HANDLE_WAIT_RET_ALERTED;
-                       break;
-               case WAIT_TIMEOUT:
-                       ret = MONO_W32HANDLE_WAIT_RET_TIMEOUT;
-                       break;
-               case WAIT_FAILED:
-                       ret = MONO_W32HANDLE_WAIT_RET_FAILED;
-                       break;
-               default:
-                       g_assert_not_reached ();
-               }
-
-               if (alerted)
-                       ret = MONO_W32HANDLE_WAIT_RET_ALERTED;
-
-               return ret;
-       }
-
-       if (!mono_w32handle_test_capabilities (handle, MONO_W32HANDLE_CAP_WAIT)) {
-               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p can't be waited for",
-                       __func__, handle);
-
-               return MONO_W32HANDLE_WAIT_RET_FAILED;
-       }
-
-       thr_ret = mono_w32handle_lock_handle (handle);
-       g_assert (thr_ret == 0);
-
-       if (mono_w32handle_test_capabilities (handle, MONO_W32HANDLE_CAP_OWN)) {
-               if (own_if_owned (handle, &statuscode)) {
-                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p already owned",
-                               __func__, handle);
-
-                       ret = statuscode == WAIT_ABANDONED_0 ? MONO_W32HANDLE_WAIT_RET_ABANDONED_0 : MONO_W32HANDLE_WAIT_RET_SUCCESS_0;
-                       goto done;
-               }
-       }
-
-       if (timeout != INFINITE)
-               start = mono_msec_ticks ();
-
-       for (;;) {
-               gint waited;
-
-               if (own_if_signalled (handle, &statuscode)) {
-                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p signalled",
-                               __func__, handle);
-
-                       ret = statuscode == WAIT_ABANDONED_0 ? MONO_W32HANDLE_WAIT_RET_ABANDONED_0 : MONO_W32HANDLE_WAIT_RET_SUCCESS_0;
-                       goto done;
-               }
-
-               mono_w32handle_ops_prewait (handle);
-
-               if (timeout == INFINITE) {
-                       waited = mono_w32handle_timedwait_signal_handle (handle, INFINITE, FALSE, alertable ? &alerted : NULL);
-               } else {
-                       gint64 elapsed;
-
-                       elapsed = mono_msec_ticks () - start;
-                       if (elapsed > timeout) {
-                               ret = MONO_W32HANDLE_WAIT_RET_TIMEOUT;
-                               goto done;
-                       }
-
-                       waited = mono_w32handle_timedwait_signal_handle (handle, timeout - elapsed, FALSE, alertable ? &alerted : NULL);
-               }
-
-               if (alerted) {
-                       ret = MONO_W32HANDLE_WAIT_RET_ALERTED;
-                       goto done;
-               }
-
-               if (waited != 0) {
-                       ret = MONO_W32HANDLE_WAIT_RET_TIMEOUT;
-                       goto done;
-               }
-       }
-
-done:
-       thr_ret = mono_w32handle_unlock_handle (handle);
-       g_assert (thr_ret == 0);
-
-       return ret;
-}
-
-MonoW32HandleWaitRet
-mono_w32handle_wait_multiple (gpointer *handles, gsize nhandles, gboolean waitall, guint32 timeout, gboolean alertable)
-{
-       MonoW32HandleWaitRet ret;
-       gboolean alerted, poll;
-       gint i, thr_ret;
-       gint64 start;
-       gpointer handles_sorted [MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS];
-       guint32 statuscodes [MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS] = {0};
-
-       if (nhandles == 0)
-               return MONO_W32HANDLE_WAIT_RET_FAILED;
-
-       if (nhandles == 1)
-               return mono_w32handle_wait_one (handles [0], timeout, alertable);
-
-       alerted = FALSE;
-
-       if (nhandles > MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS) {
-               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: too many handles: %zd",
-                       __func__, nhandles);
-
-               return MONO_W32HANDLE_WAIT_RET_FAILED;
-       }
-
-       for (i = 0; i < nhandles; ++i) {
-               if (!mono_w32handle_test_capabilities (handles[i], MONO_W32HANDLE_CAP_WAIT)
-                        && !mono_w32handle_test_capabilities (handles[i], MONO_W32HANDLE_CAP_SPECIAL_WAIT))
-               {
-                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p can't be waited for",
-                                  __func__, handles [i]);
-
-                       return MONO_W32HANDLE_WAIT_RET_FAILED;
-               }
-
-               handles_sorted [i] = handles [i];
-       }
-
-       qsort (handles_sorted, nhandles, sizeof (gpointer), g_direct_equal);
-       for (i = 1; i < nhandles; ++i) {
-               if (handles_sorted [i - 1] == handles_sorted [i]) {
-                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p is duplicated",
-                               __func__, handles_sorted [i]);
-
-                       return MONO_W32HANDLE_WAIT_RET_FAILED;
-               }
-       }
-
-       poll = FALSE;
-       for (i = 0; i < nhandles; ++i) {
-               if (mono_w32handle_get_type (handles [i]) == MONO_W32HANDLE_PROCESS) {
-                       /* Can't wait for a process handle + another handle without polling */
-                       poll = TRUE;
-               }
-       }
-
-       if (timeout != INFINITE)
-               start = mono_msec_ticks ();
-
-       for (i = 0; i < nhandles; ++i) {
-               /* Add a reference, as we need to ensure the handle wont
-                * disappear from under us while we're waiting in the loop
-                * (not lock, as we don't want exclusive access here) */
-               mono_w32handle_ref (handles [i]);
-       }
-
-       for (;;) {
-               gsize count, lowest;
-               gboolean signalled;
-               gint waited;
-
-               count = 0;
-               lowest = nhandles;
-
-               mono_w32handle_lock_handles (handles, nhandles);
-
-               for (i = 0; i < nhandles; i++) {
-                       if ((mono_w32handle_test_capabilities (handles [i], MONO_W32HANDLE_CAP_OWN) && mono_w32handle_ops_isowned (handles [i]))
-                                || mono_w32handle_issignalled (handles [i]))
-                       {
-                               count ++;
-
-                               if (i < lowest)
-                                       lowest = i;
-                       }
-               }
-
-               signalled = (waitall && count == nhandles) || (!waitall && count > 0);
-
-               if (signalled) {
-                       for (i = 0; i < nhandles; i++)
-                               own_if_signalled (handles [i], &statuscodes [i]);
-               }
-
-               mono_w32handle_unlock_handles (handles, nhandles);
-
-               if (signalled) {
-                       ret = MONO_W32HANDLE_WAIT_RET_SUCCESS_0 + lowest;
-                       for (i = lowest; i < nhandles; i++) {
-                               if (statuscodes [i] == WAIT_ABANDONED_0) {
-                                       ret = MONO_W32HANDLE_WAIT_RET_ABANDONED_0 + lowest;
-                                       break;
-                               }
-                       }
-                       goto done;
-               }
-
-               for (i = 0; i < nhandles; i++) {
-                       mono_w32handle_ops_prewait (handles[i]);
-
-                       if (mono_w32handle_test_capabilities (handles [i], MONO_W32HANDLE_CAP_SPECIAL_WAIT)
-                                && !mono_w32handle_issignalled (handles [i]))
-                       {
-                               mono_w32handle_ops_specialwait (handles [i], 0, alertable ? &alerted : NULL);
-                       }
-               }
-
-               thr_ret = mono_w32handle_lock_signal_mutex ();
-               g_assert (thr_ret == 0);
-
-               if (waitall) {
-                       signalled = TRUE;
-                       for (i = 0; i < nhandles; ++i) {
-                               if (!mono_w32handle_issignalled (handles [i])) {
-                                       signalled = FALSE;
-                                       break;
-                               }
-                       }
-               } else {
-                       signalled = FALSE;
-                       for (i = 0; i < nhandles; ++i) {
-                               if (mono_w32handle_issignalled (handles [i])) {
-                                       signalled = TRUE;
-                                       break;
-                               }
-                       }
-               }
-
-               waited = 0;
-
-               if (!signalled) {
-                       if (timeout == INFINITE) {
-                               waited = mono_w32handle_timedwait_signal (INFINITE, poll, alertable ? &alerted : NULL);
-                       } else {
-                               gint64 elapsed;
-
-                               elapsed = mono_msec_ticks () - start;
-                               if (elapsed > timeout) {
-                                       ret = MONO_W32HANDLE_WAIT_RET_TIMEOUT;
-
-                                       thr_ret = mono_w32handle_unlock_signal_mutex ();
-                                       g_assert (thr_ret == 0);
-
-                                       goto done;
-                               }
-
-                               waited = mono_w32handle_timedwait_signal (timeout - elapsed, poll, alertable ? &alerted : NULL);
-                       }
-               }
-
-               thr_ret = mono_w32handle_unlock_signal_mutex ();
-               g_assert (thr_ret == 0);
-
-               if (alerted) {
-                       ret = MONO_W32HANDLE_WAIT_RET_ALERTED;
-                       goto done;
-               }
-
-               if (waited != 0) {
-                       ret = MONO_W32HANDLE_WAIT_RET_TIMEOUT;
-                       goto done;
-               }
-       }
-
-done:
-       for (i = 0; i < nhandles; i++) {
-               /* Unref everything we reffed above */
-               mono_w32handle_unref (handles [i]);
-       }
-
-       return ret;
-}
-
-MonoW32HandleWaitRet
-mono_w32handle_signal_and_wait (gpointer signal_handle, gpointer wait_handle, guint32 timeout, gboolean alertable)
-{
-       MonoW32HandleWaitRet ret;
-       gint64 start;
-       gboolean alerted;
-       gint thr_ret;
-       guint32 statuscode = 0;
-
-       alerted = FALSE;
-
-       if (!mono_w32handle_test_capabilities (signal_handle, MONO_W32HANDLE_CAP_SIGNAL))
-               return MONO_W32HANDLE_WAIT_RET_FAILED;
-       if (!mono_w32handle_test_capabilities (wait_handle, MONO_W32HANDLE_CAP_WAIT))
-               return MONO_W32HANDLE_WAIT_RET_FAILED;
-
-       if (mono_w32handle_test_capabilities (wait_handle, MONO_W32HANDLE_CAP_SPECIAL_WAIT)) {
-               g_warning ("%s: handle %p has special wait, implement me!!", __func__, wait_handle);
-               return MONO_W32HANDLE_WAIT_RET_FAILED;
-       }
-
-       thr_ret = mono_w32handle_lock_handle (wait_handle);
-       g_assert (thr_ret == 0);
-
-       mono_w32handle_ops_signal (signal_handle);
-
-       if (mono_w32handle_test_capabilities (wait_handle, MONO_W32HANDLE_CAP_OWN)) {
-               if (own_if_owned (wait_handle, &statuscode)) {
-                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p already owned",
-                               __func__, wait_handle);
-
-                       ret = statuscode == WAIT_ABANDONED_0 ? MONO_W32HANDLE_WAIT_RET_ABANDONED_0 : MONO_W32HANDLE_WAIT_RET_SUCCESS_0;
-                       goto done;
-               }
-       }
-
-       if (timeout != INFINITE)
-               start = mono_msec_ticks ();
-
-       for (;;) {
-               gint waited;
-
-               if (own_if_signalled (wait_handle, &statuscode)) {
-                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p signalled",
-                               __func__, wait_handle);
-
-                       ret = statuscode == WAIT_ABANDONED_0 ? MONO_W32HANDLE_WAIT_RET_ABANDONED_0 : MONO_W32HANDLE_WAIT_RET_SUCCESS_0;
-                       goto done;
-               }
-
-               mono_w32handle_ops_prewait (wait_handle);
-
-               if (timeout == INFINITE) {
-                       waited = mono_w32handle_timedwait_signal_handle (wait_handle, INFINITE, FALSE, alertable ? &alerted : NULL);
-               } else {
-                       gint64 elapsed;
-
-                       elapsed = mono_msec_ticks () - start;
-                       if (elapsed > timeout) {
-                               ret = MONO_W32HANDLE_WAIT_RET_TIMEOUT;
-                               goto done;
-                       }
-
-                       waited = mono_w32handle_timedwait_signal_handle (wait_handle, timeout - elapsed, FALSE, alertable ? &alerted : NULL);
-               }
-
-               if (alerted) {
-                       ret = MONO_W32HANDLE_WAIT_RET_ALERTED;
-                       goto done;
-               }
-
-               if (waited != 0) {
-                       ret = MONO_W32HANDLE_WAIT_RET_TIMEOUT;
-                       goto done;
-               }
-       }
-
-done:
-       thr_ret = mono_w32handle_unlock_handle (wait_handle);
-       g_assert (thr_ret == 0);
-
-       return ret;
-}
-
-#endif /* !defined(HOST_WIN32) */
diff --git a/mono/utils/w32handle.h b/mono/utils/w32handle.h
deleted file mode 100644 (file)
index de65da1..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-
-#ifndef _MONO_UTILS_W32HANDLE_H_
-#define _MONO_UTILS_W32HANDLE_H_
-
-#include <config.h>
-#include <glib.h>
-
-#ifndef INVALID_HANDLE_VALUE
-#define INVALID_HANDLE_VALUE (gpointer)-1
-#endif
-
-#define MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS 64
-
-typedef enum {
-       MONO_W32HANDLE_UNUSED = 0,
-       MONO_W32HANDLE_FILE,
-       MONO_W32HANDLE_CONSOLE,
-       MONO_W32HANDLE_THREAD,
-       MONO_W32HANDLE_SEM,
-       MONO_W32HANDLE_MUTEX,
-       MONO_W32HANDLE_EVENT,
-       MONO_W32HANDLE_SOCKET,
-       MONO_W32HANDLE_FIND,
-       MONO_W32HANDLE_PROCESS,
-       MONO_W32HANDLE_PIPE,
-       MONO_W32HANDLE_NAMEDMUTEX,
-       MONO_W32HANDLE_NAMEDSEM,
-       MONO_W32HANDLE_NAMEDEVENT,
-       MONO_W32HANDLE_COUNT
-} MonoW32HandleType;
-
-typedef struct 
-{
-       void (*close)(gpointer handle, gpointer data);
-
-       /* SignalObjectAndWait */
-       void (*signal)(gpointer signal);
-
-       /* Called by WaitForSingleObject and WaitForMultipleObjects,
-        * with the handle locked (shared handles aren't locked.)
-        * Returns TRUE if ownership was established, false otherwise.
-        * If TRUE, *statuscode contains a status code such as
-        * WAIT_OBJECT_0 or WAIT_ABANDONED_0.
-        */
-       gboolean (*own_handle)(gpointer handle, guint32 *statuscode);
-
-       /* Called by WaitForSingleObject and WaitForMultipleObjects, if the
-        * handle in question is "ownable" (ie mutexes), to see if the current
-        * thread already owns this handle
-        */
-       gboolean (*is_owned)(gpointer handle);
-
-       /* Called by WaitForSingleObject and WaitForMultipleObjects,
-        * if the handle in question needs a special wait function
-        * instead of using the normal handle signal mechanism.
-        * Returns the WaitForSingleObject return code.
-        */
-       guint32 (*special_wait)(gpointer handle, guint32 timeout, gboolean *alerted);
-
-       /* Called by WaitForSingleObject and WaitForMultipleObjects,
-        * if the handle in question needs some preprocessing before the
-        * signal wait.
-        */
-       void (*prewait)(gpointer handle);
-
-       /* Called when dumping the handles */
-       void (*details)(gpointer data);
-
-       /* Called to get the name of the handle type */
-       const gchar* (*typename) (void);
-
-       /* Called to get the size of the handle type */
-       gsize (*typesize) (void);
-} MonoW32HandleOps;
-
-typedef enum {
-       MONO_W32HANDLE_CAP_WAIT         = 0x01,
-       MONO_W32HANDLE_CAP_SIGNAL       = 0x02,
-       MONO_W32HANDLE_CAP_OWN          = 0x04,
-       MONO_W32HANDLE_CAP_SPECIAL_WAIT = 0x08,
-} MonoW32HandleCapability;
-
-extern guint32 mono_w32handle_fd_reserve;
-
-void
-mono_w32handle_init (void);
-
-void
-mono_w32handle_cleanup (void);
-
-void
-mono_w32handle_register_ops (MonoW32HandleType type, MonoW32HandleOps *ops);
-
-gpointer
-mono_w32handle_new (MonoW32HandleType type, gpointer handle_specific);
-
-gpointer
-mono_w32handle_new_fd (MonoW32HandleType type, int fd, gpointer handle_specific);
-
-MonoW32HandleType
-mono_w32handle_get_type (gpointer handle);
-
-gboolean
-mono_w32handle_lookup (gpointer handle, MonoW32HandleType type, gpointer *handle_specific);
-
-gpointer
-mono_w32handle_search (MonoW32HandleType type, gboolean (*check)(gpointer, gpointer), gpointer user_data, gpointer *handle_specific, gboolean search_shared);
-
-void
-mono_w32handle_foreach (gboolean (*on_each)(gpointer handle, gpointer data, gpointer user_data), gpointer user_data);
-
-void
-mono_w32handle_dump (void);
-
-void
-mono_w32handle_ref (gpointer handle);
-
-void
-mono_w32handle_unref (gpointer handle);
-
-void
-mono_w32handle_register_capabilities (MonoW32HandleType type, MonoW32HandleCapability caps);
-
-gboolean
-mono_w32handle_test_capabilities (gpointer handle, MonoW32HandleCapability caps);
-
-void
-mono_w32handle_ops_close (gpointer handle, gpointer data);
-
-void
-mono_w32handle_ops_signal (gpointer handle);
-
-gboolean
-mono_w32handle_ops_own (gpointer handle, guint32 *statuscode);
-
-gboolean
-mono_w32handle_ops_isowned (gpointer handle);
-
-guint32
-mono_w32handle_ops_specialwait (gpointer handle, guint32 timeout, gboolean *alerted);
-
-void
-mono_w32handle_ops_prewait (gpointer handle);
-
-void
-mono_w32handle_ops_details (MonoW32HandleType type, gpointer data);
-
-const gchar*
-mono_w32handle_ops_typename (MonoW32HandleType type);
-
-gsize
-mono_w32handle_ops_typesize (MonoW32HandleType type);
-
-void
-mono_w32handle_set_signal_state (gpointer handle, gboolean state, gboolean broadcast);
-
-gboolean
-mono_w32handle_issignalled (gpointer handle);
-
-int
-mono_w32handle_lock_handle (gpointer handle);
-
-int
-mono_w32handle_trylock_handle (gpointer handle);
-
-int
-mono_w32handle_unlock_handle (gpointer handle);
-
-typedef enum {
-       MONO_W32HANDLE_WAIT_RET_SUCCESS_0   =  0,
-       MONO_W32HANDLE_WAIT_RET_ABANDONED_0 =  MONO_W32HANDLE_WAIT_RET_SUCCESS_0 + MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS,
-       MONO_W32HANDLE_WAIT_RET_ALERTED     = -1,
-       MONO_W32HANDLE_WAIT_RET_TIMEOUT     = -2,
-       MONO_W32HANDLE_WAIT_RET_FAILED      = -3,
-} MonoW32HandleWaitRet;
-
-MonoW32HandleWaitRet
-mono_w32handle_wait_one (gpointer handle, guint32 timeout, gboolean alertable);
-
-MonoW32HandleWaitRet
-mono_w32handle_wait_multiple (gpointer *handles, gsize nhandles, gboolean waitall, guint32 timeout, gboolean alertable);
-
-MonoW32HandleWaitRet
-mono_w32handle_signal_and_wait (gpointer signal_handle, gpointer wait_handle, guint32 timeout, gboolean alertable);
-
-#endif /* _MONO_UTILS_W32HANDLE_H_ */
index c51ed6b6c19ba6920e63ea67f3e54d7402f0810c..54361b9ef2db6adeb8cee68bd67b9a19b36e65f5 100644 (file)
@@ -23,6 +23,7 @@
     <ClCompile Include="..\mono\metadata\assembly.c" />\r
     <ClCompile Include="..\mono\metadata\attach.c" />\r
     <ClCompile Include="..\mono\metadata\boehm-gc.c" />\r
+    <ClCompile Include="..\mono\metadata\class-accessors.c" />\r
     <ClCompile Include="..\mono\metadata\class.c" />\r
     <ClCompile Include="..\mono\metadata\cominterop.c" />\r
     <ClCompile Include="..\mono\metadata\console-win32.c" />\r
     <ClCompile Include="..\mono\metadata\icall-windows.c" />\r
     <ClCompile Include="..\mono\metadata\marshal-windows.c" />\r
     <ClCompile Include="..\mono\metadata\mono-security-windows.c" />\r
-    <ClCompile Include="..\mono\metadata\process-windows.c" />\r
     <ClCompile Include="..\mono\metadata\w32mutex-win32.c" />\r
     <ClCompile Include="..\mono\metadata\w32semaphore-win32.c" />\r
     <ClCompile Include="..\mono\metadata\w32event-win32.c" />\r
+    <ClCompile Include="..\mono\metadata\w32process.c" />\r
+    <ClCompile Include="..\mono\metadata\w32process-win32.c" />\r
     <ClCompile Include="..\mono\metadata\coree.c" />\r
     <ClCompile Include="..\mono\metadata\custom-attrs.c" />\r
     <ClCompile Include="..\mono\metadata\debug-helpers.c" />\r
@@ -78,7 +80,6 @@
     <ClCompile Include="..\mono\metadata\number-ms.c" />\r
     <ClCompile Include="..\mono\metadata\object.c" />\r
     <ClCompile Include="..\mono\metadata\opcodes.c" />\r
-    <ClCompile Include="..\mono\metadata\process.c" />\r
     <ClCompile Include="..\mono\metadata\profiler.c" />\r
     <ClCompile Include="..\mono\metadata\rand.c" />\r
     <ClCompile Include="..\mono\metadata\reflection.c" />\r
     <ClInclude Include="..\mono\metadata\marshal-windows-internals.h" />\r
     <ClInclude Include="..\mono\metadata\mono-security-windows-internals.h" />\r
     <ClInclude Include="..\mono\metadata\number-ms.h" />\r
-    <ClInclude Include="..\mono\metadata\process-internals.h" />\r
-    <ClInclude Include="..\mono\metadata\process-windows-internals.h" />\r
+    <ClInclude Include="..\mono\metadata\w32process.h" />\r
+    <ClInclude Include="..\mono\metadata\w32process-internals.h" />\r
+    <ClInclude Include="..\mono\metadata\w32process-win32-internals.h" />\r
     <ClInclude Include="..\mono\metadata\remoting.h" />\r
     <ClInclude Include="..\mono\metadata\seq-points-data.h" />\r
     <ClInclude Include="..\mono\metadata\sgen-bridge-internals.h" />\r
     <ClInclude Include="..\mono\metadata\object-internals.h" />\r
     <ClInclude Include="..\mono\metadata\object.h" />\r
     <ClInclude Include="..\mono\metadata\opcodes.h" />\r
-    <ClInclude Include="..\mono\metadata\process.h" />\r
     <ClInclude Include="..\mono\metadata\profiler-private.h" />\r
     <ClInclude Include="..\mono\metadata\profiler.h" />\r
     <ClInclude Include="..\mono\metadata\rand.h" />\r
index e0257f56ee4d57bf89cfaaba9dcfb5db4e57cc6c..c412bbe885d12e98bc9fdd639fb5a338928b049b 100644 (file)
     <ClCompile Include="..\mono\metadata\opcodes.c">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\mono\metadata\process.c">\r
+    <ClCompile Include="..\mono\metadata\w32process.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\mono\metadata\w32process-win32.c">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\mono\metadata\profiler.c">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\mono\metadata\socket-io-windows.c">\r
-         <Filter>Source Files</Filter>\r
+      <Filter>Source Files</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\mono\metadata\file-io-windows.c">\r
       <Filter>Source Files</Filter>\r
     <ClCompile Include="..\mono\metadata\mono-security-windows.c">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\mono\metadata\process-windows.c">\r
+    <ClCompile Include="..\mono\metadata\class-accessors.c">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
   </ItemGroup>\r
     <ClInclude Include="..\mono\metadata\opcodes.h">\r
       <Filter>Header Files</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="..\mono\metadata\process.h">\r
+    <ClInclude Include="..\mono\metadata\w32process.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\mono\metadata\w32process-internals.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\mono\metadata\w32process-win32-internals.h">\r
       <Filter>Header Files</Filter>\r
     </ClInclude>\r
     <ClInclude Include="..\mono\metadata\profiler.h">\r
     <ClInclude Include="..\mono\metadata\mono-security-windows-internals.h">\r
       <Filter>Header Files</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="..\mono\metadata\process-windows-internals.h">\r
-      <Filter>Header Files</Filter>\r
-    </ClInclude>\r
-    <ClInclude Include="..\mono\metadata\process-internals.h">\r
-      <Filter>Header Files</Filter>\r
-    </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <Filter Include="Header Files">\r
index 36dc0ecaab784bf2821ed819726385cece236c45..ad0d476fd93bb58a0f64d00d9978c38a414291e0 100644 (file)
     <ClCompile Include="..\mono\metadata\metadata.c" />\r
     <ClCompile Include="..\mono\metadata\monitor.c" />\r
     <ClCompile Include="..\mono\metadata\mono-config.c" />\r
-    <ClCompile Include="..\mono\metadata\process-windows.c" />\r
     <ClCompile Include="..\mono\utils\mono-dl.c" />\r
     <ClCompile Include="..\mono\metadata\object.c" />\r
-    <ClCompile Include="..\mono\metadata\process.c" />\r
+    <ClCompile Include="..\mono\metadata\w32process.c" />\r
+    <ClCompile Include="..\mono\metadata\w32process-win32.c" />\r
     <ClCompile Include="..\mono\metadata\profiler.c" />\r
     <ClCompile Include="..\mono\metadata\rand.c" />\r
     <ClCompile Include="..\mono\metadata\reflection.c" />\r
index d05fff4fa9698c44a9e6d05351d256f696703009..72a54e162553c060c3b513b3724e503de4a7dff7 100644 (file)
     <ClCompile Include="..\mono\metadata\object.c">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\mono\metadata\process.c">\r
+    <ClCompile Include="..\mono\metadata\w32process.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\mono\metadata\w32process-win32.c">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
     <ClCompile Include="..\mono\metadata\profiler.c">\r
@@ -91,9 +94,6 @@
     <ClCompile Include="..\tools\pedump\pedump.c">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\mono\metadata\process-windows.c">\r
-      <Filter>Source Files</Filter>\r
-    </ClCompile>\r
     <ClCompile Include="..\mono\metadata\marshal-windows.c">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
index e5849b15aece7dd8642a3d9da1dba1d689833d61..348bedb9c1172f47fc9b0e7b07a39f16a7ac3945 100644 (file)
     </project>
     <project dir="tools/mono-api-html" library="mono-api-html-net_4_x">
       <boot></boot>
-      <flags>/codepage:65001 -d:NET_4_0 -d:NET_4_5 -d:NET_4_6 -d:MONO -nowarn:1699 -nostdlib -r:./../../class/lib/net_4_x/mscorlib.dll -debug -optimize /noconfig -r:Mono.Cecil -r:System.Xml -r:System.Core -r:System -r:System.Xml.Linq</flags>
+      <flags>/codepage:65001 -d:NET_4_0 -d:NET_4_5 -d:NET_4_6 -d:MONO -nowarn:1699 -nostdlib -r:./../../class/lib/net_4_x/mscorlib.dll -debug -optimize /noconfig -r:System.Xml -r:System.Core -r:System -r:System.Xml.Linq</flags>
       <output>mono-api-html.exe</output>
       <built_sources></built_sources>
       <library_output>./../../class/lib/net_4_x/mono-api-html.exe</library_output>
       <resources></resources>
       <response>System.Security.Cryptography.Cng.dll.sources</response>
     </project>
+    <project dir="class/Mono.Btls.Interface" library="Mono.Btls.Interface-monodroid">
+      <boot>false</boot>
+      <flags>/codepage:65001 -d:NET_1_1 -d:NET_2_0 -d:NET_2_1 -d:NET_3_5 -d:NET_4_0 -d:NET_4_5 -d:MONO -d:MOBILE,MOBILE_LEGACY -d:MOBILE_DYNAMIC -d:MONODROID -d:ANDROID -d:NETSTANDARD -nowarn:1699 -nostdlib -r:./../../class/lib/monodroid/mscorlib.dll -debug -optimize /noconfig -unsafe -nowarn:1030 -keyfile:../mono.pub -delaysign -d:SECURITY_DEP -r:./../../class/lib/monodroid/System.dll -r:./../../class/lib/monodroid/Mono.Security.dll</flags>
+      <output>Mono.Btls.Interface.dll</output>
+      <built_sources></built_sources>
+      <library_output>./../../class/lib/monodroid/Mono.Btls.Interface.dll</library_output>
+      <fx_version>2.1</fx_version>
+      <profile>monodroid</profile>
+      <resources></resources>
+      <response>Mono.Btls.Interface.dll.sources</response>
+    </project>
     <project dir="class/corlib" library="corlib-monotouch">
       <boot>true</boot>
       <flags>/codepage:65001 -unsafe -nostdlib -nowarn:612,618,1635 -d:INSIDE_CORLIB,MONO_CULTURE_DATA -d:LIBC -d:FEATURE_PAL,GENERICS_WORK,FEATURE_LIST_PREDICATES,FEATURE_SERIALIZATION,FEATURE_ASCII,FEATURE_LATIN1,FEATURE_UTF7,FEATURE_UTF32,MONO_HYBRID_ENCODING_SUPPORT,FEATURE_ASYNC_IO,NEW_EXPERIMENTAL_ASYNC_IO,FEATURE_UTF32,FEATURE_EXCEPTIONDISPATCHINFO,FEATURE_CORRUPTING_EXCEPTIONS,FEATURE_EXCEPTION_NOTIFICATIONS,FEATURE_STRONGNAME_MIGRATION,FEATURE_USE_LCID,FEATURE_FUSION,FEATURE_CRYPTO,FEATURE_X509_SECURESTRINGS,FEATURE_SYNCHRONIZATIONCONTEXT,FEATURE_SYNCHRONIZATIONCONTEXT_WAIT,HAS_CORLIB_CONTRACTS -d:MONO_FEATURE_THREAD_ABORT -d:MONO_FEATURE_THREAD_SUSPEND_RESUME -d:MONO_FEATURE_MULTIPLE_APPDOMAINS -d:NET_1_1 -d:NET_2_0 -d:NET_2_1 -d:NET_3_5 -d:NET_4_0 -d:NET_4_5 -d:MOBILE,MOBILE_LEGACY -d:MONO -d:MONOTOUCH -d:DISABLE_REMOTING -d:DISABLE_COM -d:FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK -d:NETSTANDARD -nowarn:1699 -nostdlib -debug -d:FULL_AOT_RUNTIME -optimize /noconfig -d:FEATURE_PAL,GENERICS_WORK,FEATURE_LIST_PREDICATES,FEATURE_SERIALIZATION,FEATURE_ASCII,FEATURE_LATIN1,FEATURE_UTF7,FEATURE_UTF32,MONO_HYBRID_ENCODING_SUPPORT,FEATURE_ASYNC_IO,NEW_EXPERIMENTAL_ASYNC_IO,FEATURE_UTF32,FEATURE_EXCEPTIONDISPATCHINFO,FEATURE_CORRUPTING_EXCEPTIONS,FEATURE_EXCEPTION_NOTIFICATIONS,FEATURE_STRONGNAME_MIGRATION,FEATURE_USE_LCID,FEATURE_FUSION,FEATURE_CRYPTO,FEATURE_X509_SECURESTRINGS,FEATURE_SYNCHRONIZATIONCONTEXT,FEATURE_SYNCHRONIZATIONCONTEXT_WAIT,HAS_CORLIB_CONTRACTS -d:MONO_FEATURE_THREAD_ABORT -d:MONO_FEATURE_THREAD_SUSPEND_RESUME -d:MONO_FEATURE_MULTIPLE_APPDOMAINS -resource:resources/charinfo.nlp -resource:resources/collation.core.bin -resource:resources/collation.tailoring.bin -resource:resources/collation.cjkCHS.bin -resource:resources/collation.cjkCHT.bin -resource:resources/collation.cjkJA.bin -resource:resources/collation.cjkKO.bin -resource:resources/collation.cjkKOlv2.bin --runtime:v4</flags>
     </project>
     <project dir="class/System" library="System-xammac">
       <boot>false</boot>
-      <flags>/codepage:65001 -d:NET_1_1 -d:NET_2_0 -d:NET_2_1 -d:NET_3_5 -d:NET_4_0 -d:NET_4_5 -d:MONO -d:MOBILE -d:MOBILE_DYNAMIC -d:XAMMAC -d:FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK -d:XAMARIN_MODERN -d:NETSTANDARD -nowarn:1699 -nostdlib -r:./../../class/lib/xammac/mscorlib.dll -debug -optimize /noconfig -d:CONFIGURATION_2_0 -d:FEATURE_PAL,SYSTEM_NAMESPACE,MONO,PLATFORM_UNIX -d:MONO_FEATURE_PROCESS_START -d:MONO_FEATURE_THREAD_ABORT -d:MONO_FEATURE_THREAD_SUSPEND_RESUME -d:MONO_FEATURE_MULTIPLE_APPDOMAINS -unsafe -d:MONO_FEATURE_BTLS -d:INSIDE_SYSTEM -d:SECURITY_DEP -nowarn:618,1635 -d:SECURITY_DEP -d:XML_DEP -r:./../../class/lib/xammac/System.Xml.dll -r:MonoSecurity=./../../class/lib/xammac/Mono.Security.dll</flags>
+      <flags>/codepage:65001 -d:NET_1_1 -d:NET_2_0 -d:NET_2_1 -d:NET_3_5 -d:NET_4_0 -d:NET_4_5 -d:MONO -d:MOBILE -d:MOBILE_DYNAMIC -d:XAMMAC -d:FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK -d:XAMARIN_MODERN -d:NETSTANDARD -nowarn:1699 -nostdlib -r:./../../class/lib/xammac/mscorlib.dll -debug -optimize /noconfig -d:CONFIGURATION_2_0 -d:FEATURE_PAL,SYSTEM_NAMESPACE,MONO,PLATFORM_UNIX -d:MONO_FEATURE_PROCESS_START -d:MONO_FEATURE_THREAD_ABORT -d:MONO_FEATURE_THREAD_SUSPEND_RESUME -d:MONO_FEATURE_MULTIPLE_APPDOMAINS -unsafe -d:INSIDE_SYSTEM -d:SECURITY_DEP -nowarn:618,1635 -d:SECURITY_DEP -d:XML_DEP -r:./../../class/lib/xammac/System.Xml.dll -r:MonoSecurity=./../../class/lib/xammac/Mono.Security.dll</flags>
       <output>System.dll</output>
       <built_sources></built_sources>
       <library_output>./../../class/lib/xammac/System.dll</library_output>
     </project>
     <project dir="class/System" library="System-bare-xammac">
       <boot>false</boot>
-      <flags>/codepage:65001 -d:NET_1_1 -d:NET_2_0 -d:NET_2_1 -d:NET_3_5 -d:NET_4_0 -d:NET_4_5 -d:MONO -d:MOBILE -d:MOBILE_DYNAMIC -d:XAMMAC -d:FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK -d:XAMARIN_MODERN -d:NETSTANDARD -nowarn:1699 -nostdlib -r:./../../class/lib/xammac/mscorlib.dll -debug -optimize /noconfig -d:CONFIGURATION_2_0 -d:FEATURE_PAL,SYSTEM_NAMESPACE,MONO,PLATFORM_UNIX -d:MONO_FEATURE_PROCESS_START -d:MONO_FEATURE_THREAD_ABORT -d:MONO_FEATURE_THREAD_SUSPEND_RESUME -d:MONO_FEATURE_MULTIPLE_APPDOMAINS -unsafe -d:MONO_FEATURE_BTLS -d:INSIDE_SYSTEM -d:SECURITY_DEP -nowarn:618,1635</flags>
+      <flags>/codepage:65001 -d:NET_1_1 -d:NET_2_0 -d:NET_2_1 -d:NET_3_5 -d:NET_4_0 -d:NET_4_5 -d:MONO -d:MOBILE -d:MOBILE_DYNAMIC -d:XAMMAC -d:FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK -d:XAMARIN_MODERN -d:NETSTANDARD -nowarn:1699 -nostdlib -r:./../../class/lib/xammac/mscorlib.dll -debug -optimize /noconfig -d:CONFIGURATION_2_0 -d:FEATURE_PAL,SYSTEM_NAMESPACE,MONO,PLATFORM_UNIX -d:MONO_FEATURE_PROCESS_START -d:MONO_FEATURE_THREAD_ABORT -d:MONO_FEATURE_THREAD_SUSPEND_RESUME -d:MONO_FEATURE_MULTIPLE_APPDOMAINS -unsafe -d:INSIDE_SYSTEM -d:SECURITY_DEP -nowarn:618,1635</flags>
       <output>System.dll</output>
       <built_sources></built_sources>
       <library_output>./../../class/lib/xammac/bare/System.dll</library_output>
     </project>
     <project dir="class/System" library="System-secxml-xammac">
       <boot>false</boot>
-      <flags>/codepage:65001 -d:NET_1_1 -d:NET_2_0 -d:NET_2_1 -d:NET_3_5 -d:NET_4_0 -d:NET_4_5 -d:MONO -d:MOBILE -d:MOBILE_DYNAMIC -d:XAMMAC -d:FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK -d:XAMARIN_MODERN -d:NETSTANDARD -nowarn:1699 -nostdlib -r:./../../class/lib/xammac/mscorlib.dll -debug -optimize /noconfig -d:CONFIGURATION_2_0 -d:FEATURE_PAL,SYSTEM_NAMESPACE,MONO,PLATFORM_UNIX -d:MONO_FEATURE_PROCESS_START -d:MONO_FEATURE_THREAD_ABORT -d:MONO_FEATURE_THREAD_SUSPEND_RESUME -d:MONO_FEATURE_MULTIPLE_APPDOMAINS -unsafe -d:MONO_FEATURE_BTLS -d:INSIDE_SYSTEM -d:SECURITY_DEP -nowarn:618,1635 -d:SECURITY_DEP -d:XML_DEP -r:./../../class/lib/xammac/bare/System.Xml.dll -r:MonoSecurity=./../../class/lib/xammac/Mono.Security.dll</flags>
+      <flags>/codepage:65001 -d:NET_1_1 -d:NET_2_0 -d:NET_2_1 -d:NET_3_5 -d:NET_4_0 -d:NET_4_5 -d:MONO -d:MOBILE -d:MOBILE_DYNAMIC -d:XAMMAC -d:FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK -d:XAMARIN_MODERN -d:NETSTANDARD -nowarn:1699 -nostdlib -r:./../../class/lib/xammac/mscorlib.dll -debug -optimize /noconfig -d:CONFIGURATION_2_0 -d:FEATURE_PAL,SYSTEM_NAMESPACE,MONO,PLATFORM_UNIX -d:MONO_FEATURE_PROCESS_START -d:MONO_FEATURE_THREAD_ABORT -d:MONO_FEATURE_THREAD_SUSPEND_RESUME -d:MONO_FEATURE_MULTIPLE_APPDOMAINS -unsafe -d:INSIDE_SYSTEM -d:SECURITY_DEP -nowarn:618,1635 -d:SECURITY_DEP -d:XML_DEP -r:./../../class/lib/xammac/bare/System.Xml.dll -r:MonoSecurity=./../../class/lib/xammac/Mono.Security.dll</flags>
       <output>System.dll</output>
       <built_sources></built_sources>
       <library_output>./../../class/lib/xammac/secxml/System.dll</library_output>
     </project>
     <project dir="class/System" library="System-xammac_net_4_5">
       <boot>false</boot>
-      <flags>/codepage:65001 -d:NET_4_0 -d:NET_4_5 -d:NET_4_6 -d:MONO -nowarn:1699 -nostdlib -r:./../../class/lib/xammac_net_4_5/mscorlib.dll -debug -d:FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK -d:NO_SYSTEM_DRAWING_DEPENDENCY -d:NO_WINFORMS_DEPENDENCY -d:NO_SYSTEM_WEB_DEPENDENCY -d:XAMMAC_4_5 -d:XAMARIN_MODERN -optimize /noconfig -d:CONFIGURATION_2_0 -d:FEATURE_PAL,SYSTEM_NAMESPACE,MONO,PLATFORM_UNIX -d:MONO_FEATURE_PROCESS_START -d:MONO_FEATURE_THREAD_ABORT -d:MONO_FEATURE_THREAD_SUSPEND_RESUME -d:MONO_FEATURE_MULTIPLE_APPDOMAINS -unsafe -resource:resources/Asterisk.wav -resource:resources/Beep.wav -resource:resources/Exclamation.wav -resource:resources/Hand.wav -resource:resources/Question.wav -d:MONO_FEATURE_BTLS -d:SECURITY_DEP -d:XML_DEP -d:MONO_SECURITY_ALIAS -d:CONFIGURATION_DEP -r:./../../class/lib/xammac_net_4_5/System.Xml.dll -r:./../../class/lib/xammac_net_4_5/System.Configuration.dll -r:MonoSecurity=./../../class/lib/xammac_net_4_5/Mono.Security.dll</flags>
+      <flags>/codepage:65001 -d:NET_4_0 -d:NET_4_5 -d:NET_4_6 -d:MONO -nowarn:1699 -nostdlib -r:./../../class/lib/xammac_net_4_5/mscorlib.dll -debug -d:FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK -d:NO_SYSTEM_DRAWING_DEPENDENCY -d:NO_WINFORMS_DEPENDENCY -d:NO_SYSTEM_WEB_DEPENDENCY -d:XAMMAC_4_5 -d:XAMARIN_MODERN -optimize /noconfig -d:CONFIGURATION_2_0 -d:FEATURE_PAL,SYSTEM_NAMESPACE,MONO,PLATFORM_UNIX -d:MONO_FEATURE_PROCESS_START -d:MONO_FEATURE_THREAD_ABORT -d:MONO_FEATURE_THREAD_SUSPEND_RESUME -d:MONO_FEATURE_MULTIPLE_APPDOMAINS -unsafe -resource:resources/Asterisk.wav -resource:resources/Beep.wav -resource:resources/Exclamation.wav -resource:resources/Hand.wav -resource:resources/Question.wav -d:SECURITY_DEP -d:XML_DEP -d:MONO_SECURITY_ALIAS -d:CONFIGURATION_DEP -r:./../../class/lib/xammac_net_4_5/System.Xml.dll -r:./../../class/lib/xammac_net_4_5/System.Configuration.dll -r:MonoSecurity=./../../class/lib/xammac_net_4_5/Mono.Security.dll</flags>
       <output>System.dll</output>
       <built_sources></built_sources>
       <library_output>./../../class/lib/xammac_net_4_5/System.dll</library_output>
     </project>
     <project dir="class/System" library="System-bare-xammac_net_4_5">
       <boot>false</boot>
-      <flags>/codepage:65001 -d:NET_4_0 -d:NET_4_5 -d:NET_4_6 -d:MONO -nowarn:1699 -nostdlib -r:./../../class/lib/xammac_net_4_5/mscorlib.dll -debug -d:FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK -d:NO_SYSTEM_DRAWING_DEPENDENCY -d:NO_WINFORMS_DEPENDENCY -d:NO_SYSTEM_WEB_DEPENDENCY -d:XAMMAC_4_5 -d:XAMARIN_MODERN -optimize /noconfig -d:CONFIGURATION_2_0 -d:FEATURE_PAL,SYSTEM_NAMESPACE,MONO,PLATFORM_UNIX -d:MONO_FEATURE_PROCESS_START -d:MONO_FEATURE_THREAD_ABORT -d:MONO_FEATURE_THREAD_SUSPEND_RESUME -d:MONO_FEATURE_MULTIPLE_APPDOMAINS -unsafe -resource:resources/Asterisk.wav -resource:resources/Beep.wav -resource:resources/Exclamation.wav -resource:resources/Hand.wav -resource:resources/Question.wav -d:MONO_FEATURE_BTLS</flags>
+      <flags>/codepage:65001 -d:NET_4_0 -d:NET_4_5 -d:NET_4_6 -d:MONO -nowarn:1699 -nostdlib -r:./../../class/lib/xammac_net_4_5/mscorlib.dll -debug -d:FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK -d:NO_SYSTEM_DRAWING_DEPENDENCY -d:NO_WINFORMS_DEPENDENCY -d:NO_SYSTEM_WEB_DEPENDENCY -d:XAMMAC_4_5 -d:XAMARIN_MODERN -optimize /noconfig -d:CONFIGURATION_2_0 -d:FEATURE_PAL,SYSTEM_NAMESPACE,MONO,PLATFORM_UNIX -d:MONO_FEATURE_PROCESS_START -d:MONO_FEATURE_THREAD_ABORT -d:MONO_FEATURE_THREAD_SUSPEND_RESUME -d:MONO_FEATURE_MULTIPLE_APPDOMAINS -unsafe -resource:resources/Asterisk.wav -resource:resources/Beep.wav -resource:resources/Exclamation.wav -resource:resources/Hand.wav -resource:resources/Question.wav</flags>
       <output>System.dll</output>
       <built_sources></built_sources>
       <library_output>./../../class/lib/xammac_net_4_5/bare/System.dll</library_output>
     </project>
     <project dir="class/System" library="System-secxml-xammac_net_4_5">
       <boot>false</boot>
-      <flags>/codepage:65001 -d:NET_4_0 -d:NET_4_5 -d:NET_4_6 -d:MONO -nowarn:1699 -nostdlib -r:./../../class/lib/xammac_net_4_5/mscorlib.dll -debug -d:FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK -d:NO_SYSTEM_DRAWING_DEPENDENCY -d:NO_WINFORMS_DEPENDENCY -d:NO_SYSTEM_WEB_DEPENDENCY -d:XAMMAC_4_5 -d:XAMARIN_MODERN -optimize /noconfig -d:CONFIGURATION_2_0 -d:FEATURE_PAL,SYSTEM_NAMESPACE,MONO,PLATFORM_UNIX -d:MONO_FEATURE_PROCESS_START -d:MONO_FEATURE_THREAD_ABORT -d:MONO_FEATURE_THREAD_SUSPEND_RESUME -d:MONO_FEATURE_MULTIPLE_APPDOMAINS -unsafe -resource:resources/Asterisk.wav -resource:resources/Beep.wav -resource:resources/Exclamation.wav -resource:resources/Hand.wav -resource:resources/Question.wav -d:MONO_FEATURE_BTLS -d:SECURITY_DEP -d:XML_DEP -d:MONO_SECURITY_ALIAS -r:./../../class/lib/xammac_net_4_5/bare/System.Xml.dll -r:MonoSecurity=./../../class/lib/xammac_net_4_5/Mono.Security.dll</flags>
+      <flags>/codepage:65001 -d:NET_4_0 -d:NET_4_5 -d:NET_4_6 -d:MONO -nowarn:1699 -nostdlib -r:./../../class/lib/xammac_net_4_5/mscorlib.dll -debug -d:FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK -d:NO_SYSTEM_DRAWING_DEPENDENCY -d:NO_WINFORMS_DEPENDENCY -d:NO_SYSTEM_WEB_DEPENDENCY -d:XAMMAC_4_5 -d:XAMARIN_MODERN -optimize /noconfig -d:CONFIGURATION_2_0 -d:FEATURE_PAL,SYSTEM_NAMESPACE,MONO,PLATFORM_UNIX -d:MONO_FEATURE_PROCESS_START -d:MONO_FEATURE_THREAD_ABORT -d:MONO_FEATURE_THREAD_SUSPEND_RESUME -d:MONO_FEATURE_MULTIPLE_APPDOMAINS -unsafe -resource:resources/Asterisk.wav -resource:resources/Beep.wav -resource:resources/Exclamation.wav -resource:resources/Hand.wav -resource:resources/Question.wav -d:SECURITY_DEP -d:XML_DEP -d:MONO_SECURITY_ALIAS -r:./../../class/lib/xammac_net_4_5/bare/System.Xml.dll -r:MonoSecurity=./../../class/lib/xammac_net_4_5/Mono.Security.dll</flags>
       <output>System.dll</output>
       <built_sources></built_sources>
       <library_output>./../../class/lib/xammac_net_4_5/secxml/System.dll</library_output>
       <resources></resources>
       <response>System.Net.Http.WebRequest.dll.sources</response>
     </project>
-    <project dir="class/Mono.Btls.Interface" library="Mono.Btls.Interface-xammac_net_4_5">
-      <boot>false</boot>
-      <flags>/codepage:65001 -d:NET_4_0 -d:NET_4_5 -d:NET_4_6 -d:MONO -nowarn:1699 -nostdlib -r:./../../class/lib/xammac_net_4_5/mscorlib.dll -debug -d:FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK -d:NO_SYSTEM_DRAWING_DEPENDENCY -d:NO_WINFORMS_DEPENDENCY -d:NO_SYSTEM_WEB_DEPENDENCY -d:XAMMAC_4_5 -d:XAMARIN_MODERN -optimize /noconfig -unsafe -nowarn:1030 -keyfile:../mono.pub -delaysign -d:SECURITY_DEP -r:./../../class/lib/xammac_net_4_5/System.dll -r:./../../class/lib/xammac_net_4_5/Mono.Security.dll</flags>
-      <output>Mono.Btls.Interface.dll</output>
-      <built_sources></built_sources>
-      <library_output>./../../class/lib/xammac_net_4_5/Mono.Btls.Interface.dll</library_output>
-      <fx_version>4.5</fx_version>
-      <profile>xammac_net_4_5</profile>
-      <resources></resources>
-      <response>Mono.Btls.Interface.dll.sources</response>
-    </project>
     <project dir="class/System.Runtime.InteropServices.RuntimeInformation" library="System.Runtime.InteropServices.RuntimeInformation-xammac_net_4_5">
       <boot>false</boot>
       <flags>/codepage:65001 -d:NET_4_0 -d:NET_4_5 -d:NET_4_6 -d:MONO -nowarn:1699 -nostdlib -r:./../../class/lib/xammac_net_4_5/mscorlib.dll -debug -d:FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK -d:NO_SYSTEM_DRAWING_DEPENDENCY -d:NO_WINFORMS_DEPENDENCY -d:NO_SYSTEM_WEB_DEPENDENCY -d:XAMMAC_4_5 -d:XAMARIN_MODERN -optimize /noconfig -r:./../../class/lib/xammac_net_4_5/System.dll</flags>
index fa96ad7cef28cd13fe0aba1d1fdeb1df9860b2b4..91c9b11c9c5b1d751a2660da205ff0080118ee9d 100755 (executable)
@@ -25,7 +25,7 @@ fi
 ${TESTCMD} --label=System.Data --timeout=5m make -w -C mcs/class/System.Data run-test
 ${TESTCMD} --label=System.Data.OracleClient --timeout=5m make -w -C mcs/class/System.Data.OracleClient run-test;
 ${TESTCMD} --label=System.Design --timeout=5m make -w -C mcs/class/System.Design run-test;
-if [[ -n "${ghprbPullId}" ]] && [[ ${label} == w* ]]; then ${TESTCMD} --label=Mono.Posix --skip; else ${TESTCMD} --label=Mono.Posix --timeout=5m make -w -C mcs/class/Mono.Posix run-test; fi
+${TESTCMD} --label=Mono.Posix --timeout=5m make -w -C mcs/class/Mono.Posix run-test
 ${TESTCMD} --label=System.Web --timeout=30m make -w -C mcs/class/System.Web run-test
 ${TESTCMD} --label=System.Web.Services --timeout=5m make -w -C mcs/class/System.Web.Services run-test
 ${TESTCMD} --label=System.Runtime.SFS --timeout=5m make -w -C mcs/class/System.Runtime.Serialization.Formatters.Soap run-test;
index f364a66095fcaf23a35524746f18d4accf891736..9dcebc7e967d6b04e9d8780c6cf7807e51bac228 100644 (file)
@@ -194,21 +194,22 @@ ReadZStream (ZStream *stream, guchar *buffer, gint length)
        while (zs->avail_out > 0) {
                if (zs->avail_in == 0) {
                        n = stream->func (stream->buffer, BUFFER_SIZE, stream->gchandle);
+                       n = n < 0 ? 0 : n;
                        stream->total_in += n;
-                       if (n <= 0) {
-                               stream->eof = TRUE;
-                       }
                        zs->next_in = stream->buffer;
-                       zs->avail_in = n < 0 ? 0 : n;
+                       zs->avail_in = n;
                }
 
-               if (zs->avail_in == 0 && (zs->total_in == 0 || stream->total_in == zs->total_in))
-                       return Z_STREAM_END;
+               if (zs->avail_in == 0 && zs->total_in == 0)
+                       return 0;
 
                status = inflate (stream->stream, Z_SYNC_FLUSH);
                if (status == Z_STREAM_END) {
                        stream->eof = TRUE;
                        break;
+               } else if (status == Z_BUF_ERROR && stream->total_in == zs->total_in) {
+                       stream->eof = TRUE;
+                       break;
                } else if (status != Z_OK) {
                        return status;
                }
index 27f1a5f3cf9cf801d857e750382395fcb80cccff..4d3cb8370693ebaa8616f7bc163d43ef3bc7d8fb 100644 (file)
@@ -260,9 +260,9 @@ method_stats (MonoMethod *method) {
                        if (i == MONO_CEE_CASTCLASS || i == MONO_CEE_ISINST) {
                                guint32 token = read32 (ip + 1);
                                MonoClass *k = mono_class_get (method->klass->image, token);
-                               if (k && k->flags & TYPE_ATTRIBUTE_SEALED)
+                               if (k && mono_class_get_flags (k) & TYPE_ATTRIBUTE_SEALED)
                                        cast_sealed++;
-                               if (k && k->flags & TYPE_ATTRIBUTE_INTERFACE)
+                               if (k && mono_class_get_flags (k) & TYPE_ATTRIBUTE_INTERFACE)
                                        cast_iface++;
                                total_cast++;
                        }
@@ -364,7 +364,7 @@ method_stats (MonoMethod *method) {
                                MonoMethod *cm = mono_get_method (method->klass->image, read32 (ip + 1), NULL);
                                if (cm && !(cm->flags & METHOD_ATTRIBUTE_VIRTUAL))
                                        nonvirt_callvirt++;
-                               if (cm && (cm->klass->flags & TYPE_ATTRIBUTE_INTERFACE))
+                               if (cm && (mono_class_get_flags (cm->klass) & TYPE_ATTRIBUTE_INTERFACE))
                                        iface_callvirt++;
                                total_callvirt++;
                        }
@@ -430,7 +430,7 @@ type_stats (MonoClass *klass) {
        MonoClass *parent;
        int depth = 1;
 
-       if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
+       if (mono_class_get_flags (klass) & TYPE_ATTRIBUTE_INTERFACE) {
                num_ifaces++;
                return;
        }