Merge pull request #3871 from akoeplinger/mono.posix-windows
authorAlexander Köplinger <alex.koeplinger@outlook.com>
Thu, 3 Nov 2016 19:48:54 +0000 (20:48 +0100)
committerGitHub <noreply@github.com>
Thu, 3 Nov 2016 19:48:54 +0000 (20:48 +0100)
[Mono.Posix] Disable Unix-specific tests on Windows

101 files changed:
eglib/src/goutput.c
mcs/class/Microsoft.Build.Tasks/Makefile
mcs/class/corlib/Test/System.IO.IsolatedStorage/IsolatedStorageFileStreamTest.cs
mcs/class/corlib/Test/System/TypeTest.cs
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/cs1904.cs [deleted file]
mcs/mcs/report.cs
mcs/mcs/settings.cs
mcs/tools/corcompare/mono-api-info.csproj
mcs/tools/mono-api-html/Makefile
mono/dis/get.c
mono/io-layer/Makefile.am
mono/io-layer/access.h [deleted file]
mono/io-layer/io.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/timefuncs-private.h [deleted file]
mono/io-layer/timefuncs.c
mono/io-layer/timefuncs.h
mono/io-layer/uglify.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/assembly.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/gc.c
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.c
mono/metadata/metadata.c
mono/metadata/metadata.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.c
mono/metadata/seq-points-data.c
mono/metadata/sgen-new-bridge.c
mono/metadata/sgen-tarjan-bridge.c
mono/metadata/sre-encode.c
mono/metadata/sre-save.c
mono/metadata/sre.c
mono/metadata/threads.c
mono/metadata/verify.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/mini/aot-compiler.c
mono/mini/aot-runtime.c
mono/mini/debugger-agent.c
mono/mini/driver.c
mono/mini/jit-icalls.c
mono/mini/main.c
mono/mini/method-to-ir.c
mono/mini/mini-exceptions.c
mono/mini/mini-generic-sharing.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/trace.c
mono/sgen/sgen-gc.h
mono/utils/mach-support-arm.c
mono/utils/mach-support-arm64.c
mono/utils/mach-support-unknown.c
mono/utils/mono-context.h
msvc/libmonoruntime.vcxproj
msvc/libmonoruntime.vcxproj.filters
msvc/pedump.vcxproj
msvc/pedump.vcxproj.filters
tools/monograph/monograph.c

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 c1504f3d79141e4dc677bd7a7fd6e6f195e74378..a919129b083e53916526a0ea1316dc6f313f5771 100644 (file)
@@ -25,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:$@ $<
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 d70e5fdde709fd20dcbcf54bf9fa7e338d5483bb..14ee1b5684ad56655eab8c8d5f9ccf6afe506b03 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
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/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 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 b3108a570143f39a399a02cc991aa92dd69e38fc..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)
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 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 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 a2e2f78d9c761b10d788ba2b1237b73bdcd3d6ae..3106fc13078bbd75f986b6eb143eb92d91197a95 100644 (file)
@@ -39,7 +39,7 @@
 #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>
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 235e8be..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/metadata/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_ */
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 5af19d33387b2cfc29695c32f7f458bff18a9035..9be764c15218771e3bb46150829b67b85286ca1d 100644 (file)
@@ -26,7 +26,6 @@ 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/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 a0a8b93c64ec1115aa2b29e4e57707eae7fa5cc7..f162b0bb45cad926593816f8e28366fcfd034dd7 100644 (file)
@@ -3,7 +3,6 @@
 
 #include "io-trace.h"
 #include "io.h"
-#include "process-private.h"
 #include "socket-private.h"
 
 #include "mono/utils/mono-lazy-init.h"
@@ -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 86de9a7c062be7606101de9ebc503ad54b309efe..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                  \
index 9efcf1db486445dec64ee79c733593dbd7511391..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*
@@ -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 1
-       MonoCustomAttrInfo *attrs = mono_custom_attrs_from_assembly_checked (assembly, TRUE, 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,26 +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);
-
-       image->assembly = ass;
-
        /* 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
@@ -2008,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);
@@ -2029,6 +2010,26 @@ 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);
        mono_assemblies_unlock ();
 
diff --git a/mono/metadata/class-accessors.c b/mono/metadata/class-accessors.c
new file mode 100644 (file)
index 0000000..e28f7fd
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * 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;
+}
diff --git a/mono/metadata/class-inlines.h b/mono/metadata/class-inlines.h
new file mode 100644 (file)
index 0000000..d63c6a8
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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 *class)
+{
+       return class->class_kind == MONO_CLASS_DEF;
+}
+
+static inline gboolean
+mono_class_is_gtd (MonoClass *class)
+{
+       return class->class_kind == MONO_CLASS_GTD;
+}
+
+static inline gboolean
+mono_class_is_ginst (MonoClass *class)
+{
+       return class->class_kind == MONO_CLASS_GINST;
+}
+
+static inline gboolean
+mono_class_is_gparam (MonoClass *class)
+{
+       return class->class_kind == MONO_CLASS_GPARAM;
+}
+
+static inline gboolean
+mono_class_is_array (MonoClass *class)
+{
+       return class->class_kind == MONO_CLASS_ARRAY;
+}
+
+static inline gboolean
+mono_class_is_pointer (MonoClass *class)
+{
+       return class->class_kind == MONO_CLASS_POINTER;
+}
+
+static inline gboolean
+mono_class_is_abstract (MonoClass *class)
+{
+       return mono_class_get_flags (class) & TYPE_ATTRIBUTE_ABSTRACT;
+}
+
+static inline gboolean
+mono_class_is_interface (MonoClass *class)
+{
+       return mono_class_get_flags (class) & TYPE_ATTRIBUTE_INTERFACE;
+}
+
+#endif
\ No newline at end of file
index 8cab0c064b691bfa462c2116328648b710e76c2d..77b78dad4ef8e6e8f2702ed8ec985142e9e7459e 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; 
@@ -315,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 */
@@ -357,7 +365,6 @@ struct _MonoClass {
        /*
         * From the TypeDef table
         */
-       guint32    flags;
        struct {
 #if MONO_SMALL_CONFIG
                guint16 first, count;
@@ -383,16 +390,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;
 
@@ -400,6 +401,35 @@ struct _MonoClass {
        MonoClassExt *ext;
 };
 
+typedef struct {
+       MonoClass class;
+       guint32 flags;
+       /* 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);
@@ -1336,9 +1366,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);
 
@@ -1431,4 +1458,23 @@ 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);
+
+/*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 6b756589023be1a4a175abd0925c1de1c0b2c960..49aad3f4a7281534788d4f0234f7d8bf3f65d736 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;
@@ -506,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;
@@ -536,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;
@@ -545,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, '>');
@@ -667,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;
        }
@@ -790,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;
@@ -827,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;
 }
 
 /*
@@ -1084,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);
@@ -1095,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);
@@ -1160,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) {
@@ -1240,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;
 }
 
@@ -1312,12 +1287,11 @@ mono_class_find_enum_basetype (MonoClass *klass, MonoError *error)
 
        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);
        }
 
@@ -1353,7 +1327,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))
@@ -1407,8 +1381,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);
 }
@@ -1439,6 +1414,7 @@ mono_class_alloc0 (MonoClass *klass, int size)
 static void
 mono_class_setup_basic_field_info (MonoClass *klass)
 {
+       MonoGenericClass *gklass;
        MonoClassField *field;
        MonoClassField *fields;
        MonoClass *gtd;
@@ -1448,10 +1424,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
@@ -1547,19 +1525,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
@@ -1572,7 +1551,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"))
@@ -1640,7 +1618,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;
                        }
@@ -1773,7 +1751,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;
@@ -2242,9 +2220,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))
@@ -2407,13 +2385,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,
@@ -2443,7 +2422,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);
@@ -2488,9 +2467,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];
 
@@ -2539,8 +2518,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);
@@ -2670,8 +2649,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);
@@ -2861,7 +2840,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);
@@ -2880,8 +2859,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;
@@ -3137,11 +3117,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;
@@ -3682,7 +3663,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;
@@ -3809,16 +3790,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)
@@ -3889,7 +3871,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);
@@ -3897,9 +3879,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;
        }
 
@@ -4427,9 +4409,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);
@@ -4646,7 +4628,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;
@@ -4790,7 +4772,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);
@@ -4803,8 +4785,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);
 
@@ -4907,14 +4889,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) {
@@ -5055,7 +5037,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++) {
@@ -5147,8 +5129,10 @@ mono_class_init (MonoClass *klass)
                        goto leave;
        }
 
-       if (klass->generic_class && !klass->generic_class->is_dynamic) {
-               MonoClass *gklass = klass->generic_class->container_class;
+       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_class_init (gklass);
                if (mono_class_set_type_load_failure_causedby_class (klass, gklass, "Generic Type Definition failed to init"))
@@ -5198,8 +5182,8 @@ mono_class_init (MonoClass *klass)
                } else {
                        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 */
                ghcimpl = gklass->ghcimpl;
@@ -5285,8 +5269,8 @@ 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;
+       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++;
 
@@ -5294,7 +5278,7 @@ mono_class_init (MonoClass *klass)
                klass->field = gklass->field;
        }
 
-       if (klass->generic_class || image_is_dynamic (klass->image) || !klass->type_token || (has_cached_info && !cached_info.has_nested_classes))
+       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;
@@ -5315,7 +5299,7 @@ mono_class_init (MonoClass *klass)
        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;
@@ -5353,8 +5337,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) {
@@ -5600,7 +5584,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
@@ -5700,7 +5684,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. */
@@ -5762,7 +5746,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;
@@ -5771,25 +5765,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;
@@ -5817,7 +5807,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;
                        }
@@ -5829,7 +5819,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);
 
        /* 
@@ -5847,11 +5837,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
 
@@ -5924,7 +5914,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);
@@ -5953,8 +5943,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;
 }
 
 
@@ -5963,7 +5953,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
@@ -5971,7 +5961,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)) {
@@ -6009,7 +5999,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;
 
@@ -6027,12 +6017,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;
@@ -6082,8 +6072,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 ();
 
@@ -6144,8 +6134,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 );
@@ -6195,7 +6187,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;
@@ -6421,21 +6412,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;
@@ -6485,15 +6477,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;
@@ -6700,10 +6695,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);
@@ -6719,11 +6716,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);
 
@@ -6746,7 +6742,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);
        mono_class_init_sizes (eclass);
        mono_class_set_type_load_failure_causedby_class (klass, eclass, "Could not load array element type");
@@ -6802,7 +6798,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;
@@ -8104,10 +8101,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))
@@ -8151,7 +8148,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;
@@ -8160,8 +8157,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]);
@@ -8416,14 +8413,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]);
@@ -8600,8 +8597,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);
 }
@@ -8982,22 +8979,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
@@ -9870,8 +9851,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);
@@ -10003,16 +9984,29 @@ mono_classes_init (void)
        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);
 }
 
 /**
@@ -10067,7 +10061,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;
 }
 
 /*
@@ -10164,8 +10159,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;
@@ -10219,12 +10215,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)))
@@ -10275,15 +10271,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;
@@ -10532,7 +10529,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_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK) != TYPE_ATTRIBUTE_AUTO_LAYOUT)
                return FALSE;
 
        while ((field = mono_class_get_fields (klass, &iter))) {
@@ -10557,7 +10554,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;
 }
 
 /*
@@ -10595,6 +10592,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);
 }
 
@@ -10629,8 +10627,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)) {
@@ -10641,7 +10639,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;
@@ -10671,7 +10669,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);
@@ -10700,10 +10698,10 @@ mono_field_resolve_type (MonoClassField *field, MonoError *error)
                /*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);
                }
 
@@ -10738,7 +10736,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;
 
 
index 5f7d15560aa1c3c83d20b8664b7ae7cfe4517e34..39a808dc8b2b4761c0a80add4c2c9855dc90d270 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_get_flags (klass) & TYPE_ATTRIBUTE_PUBLIC) )
                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 fc57ecf34b4c1b8b83e91719fa9a482c23c25424..52bceeaa3511028cb5788ca0cc90f73a506f615f 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;
@@ -1210,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);
@@ -1710,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 416d9350d457ee40de9d018536ac2beb28a8bd3b..50c24b26cc1a3eb2656de12ef7d099046473c735 100644 (file)
@@ -732,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_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT)
                                return (gpointer)-1;
                        return (char*)obj + sizeof (MonoObject);
                }
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 988404dbbdb1f76a4aef6520033e92cb07041013..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);
@@ -2358,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;
@@ -2393,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) {
@@ -2718,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;
@@ -2732,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;
@@ -2762,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*
@@ -2777,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);
@@ -2830,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;
        }
@@ -2853,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
@@ -3174,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;
        }
@@ -4287,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 {
@@ -5083,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;
@@ -6973,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);
@@ -7036,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;
        }
@@ -7343,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:
@@ -7382,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);
@@ -7406,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;
                }
 
        }
@@ -7957,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)
@@ -8003,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..13da8b29e39c0a41f5fb0f655c42498f44b90174 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,8 +362,8 @@ 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)) {
                for (i = 0; i < klass->method.count; ++i) {
                        guint32 cols [MONO_METHOD_SIZE];
                        MonoMethod *method;
@@ -668,7 +668,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 +854,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 +941,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 +1659,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 +2374,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 +2579,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);
 }
 
index a9a1042aee535ed693236c55c534486013e9e3ed..1fe85c19bc3c1aecb6401c8b52c0b073d182c59e 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;
@@ -352,6 +354,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);
+
        }
 }
 
@@ -1964,7 +1970,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_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT) {
                        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 +2005,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_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) && (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 +3270,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 +3328,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,7 +4944,7 @@ emit_marshal_vtype (EmitMarshalContext *m, int argnum, MonoType *t,
                        break;
                }
 
-               if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
+               if (((mono_class_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
                        klass->blittable || klass->enumtype)
                        break;
 
@@ -4985,7 +4991,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) ||
+                       if (((mono_class_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
                                klass->blittable || klass->enumtype)
                                mono_mb_emit_ldarg_addr (mb, argnum);
                        else
@@ -5001,7 +5007,7 @@ emit_marshal_vtype (EmitMarshalContext *m, int argnum, MonoType *t,
                        break;
                }
 
-               if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
+               if (((mono_class_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
                        klass->blittable || klass->enumtype) {
                        mono_mb_emit_ldarg (mb, argnum);
                        break;
@@ -5034,7 +5040,7 @@ emit_marshal_vtype (EmitMarshalContext *m, int argnum, MonoType *t,
                        break;
                }
 
-               if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
+               if (((mono_class_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
                        klass->blittable || klass->enumtype)
                        break;
 
@@ -5063,7 +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) ||
+               if (((mono_class_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
                        klass->blittable) {
                        mono_mb_emit_stloc (mb, 3);
                        break;
@@ -5083,7 +5089,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) ||
+               if (((mono_class_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
                        klass->blittable || klass->enumtype) {
                        conv_arg = 0;
                        break;
@@ -5116,7 +5122,7 @@ 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) ||
+               if (((mono_class_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
                        klass->blittable || klass->enumtype) {
                        break;
                }
@@ -5143,7 +5149,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) ||
+               if (((mono_class_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
                        klass->blittable || klass->enumtype) {
                        mono_mb_emit_stloc (mb, 3);
                        m->retobj_var = 0;
@@ -5476,7 +5482,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 +5941,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_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT) {
                        mono_mb_emit_auto_layout_exception (mb, klass);
                        break;
                }
@@ -6055,7 +6061,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_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT) {
                        mono_mb_emit_auto_layout_exception (mb, klass);
                        break;
                }
@@ -7516,7 +7522,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_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) || 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 +8261,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_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) || 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 +9286,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 +9340,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 +9567,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_get_flags (element_class) & TYPE_ATTRIBUTE_SEALED) || element_class->valuetype;
 }
 
 static int
@@ -9581,7 +9587,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_get_flags (element_class) & TYPE_ATTRIBUTE_SEALED)
                return STELEMREF_SEALED_CLASS;
        return STELEMREF_CLASS;
 }
@@ -10798,7 +10804,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 +11283,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 +11389,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,10 +11651,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_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT)
                        break;
 
-               if (klass->valuetype && (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
+               if (klass->valuetype && (((mono_class_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
                        klass->blittable || klass->enumtype))
                        return mono_object_unbox (o);
 
@@ -11709,7 +11716,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) ||
+               if (klass->valuetype && (((mono_class_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
                                                                 klass->blittable || klass->enumtype))
                        break;
 
index 3a4c22860f7c7b022e10743442037436c061c718..bcff8a66261a48b03da3b3165b1793036efe87c8 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;
@@ -2994,7 +2994,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 +3089,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 +4804,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 +4959,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 +6610,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 +6628,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 +6646,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 5a57b2fc6d04d7921143f2a9197298417adba2bc..78fe267412243c68b3731c189e923d828d31da17 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 */
@@ -2290,7 +2290,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 +2448,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 +2459,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 +2548,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 +2595,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 +2696,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 +2767,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 +6487,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 +6523,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 +7843,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 079048c..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/metadata/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 e17bf8692087481ac62bb52e93ba94263d8ecd34..1076479daa0b1c961f62cefbcc984cd28bc5dbee 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,7 +2156,7 @@ 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;
@@ -2169,7 +2178,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 +2224,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 +2354,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 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 3c7454885210dda167c0870bec22bed4b5d79ed2..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;
                }
index 3256f8cb1990d4e3b18a5d2e8e92d668ada6fa08..5ee8fce47d94fc5201b7c1b25cb5f6eb16665fb8 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_get_flags (klass) & TYPE_ATTRIBUTE_PUBLIC)
                        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 587887dc3f0772d3e0ff4cde05e58457e174927f..db893444c1f819f5b120038679b44f3b591f4016 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];
@@ -3428,7 +3436,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 +3498,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 +3749,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 3c19e69732c568ebd60511749b995153fee367c3..e1a046eee907548fc764bd50f9701cccf0a926c7 100644 (file)
@@ -2853,13 +2853,6 @@ 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)
index 7be7267baa5d7bdb303b6809640bb58b9f88c18b..47191f4fa7bb352f8be197906d0789953d51bb78 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_get_flags (method->klass) & TYPE_ATTRIBUTE_SEALED) && !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_get_flags (method->klass) & TYPE_ATTRIBUTE_SEALED)) {
                        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_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT))
                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_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT)
                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;
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..dfc9578
--- /dev/null
@@ -0,0 +1,623 @@
+
+#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, modules, size, &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 9b606579522a8f000722179b1806288878ad7013..bf043ec27a41175a5b881d4d7f6d47c1be9d19c3 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;
@@ -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_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT)
                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_get_flags (callee_cfg->method->klass) & TYPE_ATTRIBUTE_BEFORE_FIELD_INIT)))
                                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 ?
@@ -6273,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)
@@ -7330,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) {
@@ -7467,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;
        }
@@ -7646,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;
                        }
@@ -7654,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;
                        }
@@ -8193,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 
@@ -8631,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;
 
@@ -8649,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);
 
@@ -9747,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);
 
@@ -9768,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);
index bcd2ddefb5c0ea23bf2b0d583986b590bf028765..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);
@@ -4213,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;
@@ -4280,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 3063ab4d3af3ee4ff51daa662763424e693ae48e..ec40de9a8bc83cb65a81e1d54d372fc64adda781 100644 (file)
@@ -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 55d610b5ac3b2f41dcffd7101f9f2b6c67ba63b4..7d0716dad90c909c3d68fd2f59b0f2af827ad276 100644 (file)
@@ -49,6 +49,7 @@
 #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"
@@ -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 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..80044897a83e48a34caee27a8aa05d1a92e74edc 100644 (file)
@@ -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 0a8cefa1566ffefb6104b46f5148954ba66f58a2..28261c5338f544b708c125f36eebe65ff23b8d17 100644 (file)
@@ -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_get_flags (klass) & TYPE_ATTRIBUTE_SEALED) || 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_get_flags (klass) & TYPE_ATTRIBUTE_SEALED)) {
                        /* 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_get_flags (klass) & TYPE_ATTRIBUTE_SEALED)) {
                                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_get_flags (method->klass) & TYPE_ATTRIBUTE_BEFORE_FIELD_INIT) {
                        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_get_flags (method->klass) & TYPE_ATTRIBUTE_BEFORE_FIELD_INIT)))
                        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_get_flags (klass) & TYPE_ATTRIBUTE_BEFORE_FIELD_INIT) {
                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;
@@ -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);
                        }
@@ -15125,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 120da0bc2bc49355b6d09d2f16b3766762e1fa5d..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));
 
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 5d5dd022c9e01daa2ed2339bdf07fd511b301ace..c926eed54739540f645f428a67fdcc774faec968 100644 (file)
@@ -1476,7 +1476,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_get_flags (vtable->klass) & TYPE_ATTRIBUTE_BEFORE_FIELD_INIT) && (method && mono_class_needs_cctor_run (vtable->klass, method)))
                        /* Done by the generated code */
                        ;
                else {
@@ -3103,7 +3103,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)
@@ -4218,7 +4218,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..5926caff051541052258f40c8cf59d04d916b272 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_get_flags (method->klass) & TYPE_ATTRIBUTE_SEALED) || !(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 492295493441cd6883abcabbba259b35b3eca6b3..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
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 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 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 2a95f8044e087a7ef2e49b9d75f704f4e3cc2b4b..7e8ad4cb88fa31411986d632e318b243a402d2a8 100644 (file)
@@ -405,7 +405,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 c51ed6b6c19ba6920e63ea67f3e54d7402f0810c..44de539dd894d00c1ce9df0a673f148f058d1ff0 100644 (file)
     <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 +79,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..af651a02c4d9524b36a2041f7d42199866c8ae54 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
     <ClCompile Include="..\mono\metadata\mono-security-windows.c">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\mono\metadata\process-windows.c">\r
-      <Filter>Source Files</Filter>\r
-    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClInclude Include="..\mono\metadata\appdomain.h">\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 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;
        }