Merge pull request #3528 from BrzVlad/fix-sgen-check-before-collections
authorVlad Brezae <brezaevlad@gmail.com>
Thu, 8 Sep 2016 23:54:48 +0000 (02:54 +0300)
committerGitHub <noreply@github.com>
Thu, 8 Sep 2016 23:54:48 +0000 (02:54 +0300)
[sgen] Fix sgen debug flags

452 files changed:
acceptance-tests/Makefile.am
acceptance-tests/SUBMODULES.json
acceptance-tests/profiler-stress.mk [new file with mode: 0644]
acceptance-tests/profiler-stress/runner.cs [new file with mode: 0644]
acceptance-tests/profiler-stress/runner.exe.sources [new file with mode: 0644]
acceptance-tests/versions.mk
configure.ac
docs/sources/mono-api-gc.html
eglib/src/gmisc-win32.c
external/cecil
libgc/include/gc.h
man/Makefile.am
man/cert-sync.1 [new file with mode: 0644]
man/mkbundle.1
man/mprof-report.1
mcs/build/tests.make
mcs/class/Facades/Microsoft.Win32.Registry.AccessControl/RegistryAclExtensions.cs
mcs/class/Facades/System.Diagnostics.StackTrace/StackFrameExtensions.cs
mcs/class/Facades/System.Globalization.Extensions/StringNormalizationExtensions.cs
mcs/class/Facades/System.IO.FileSystem.AccessControl/FileSystemAclExtensions.cs
mcs/class/Facades/System.Net.Sockets/SocketTaskExtensions.cs
mcs/class/Facades/System.Private.CoreLib.InteropServices/AssemblyInfo.cs [deleted file]
mcs/class/Facades/System.Private.CoreLib.InteropServices/Facades_System.Private.CoreLib.InteropServices-net_4_x.csproj [deleted file]
mcs/class/Facades/System.Private.CoreLib.InteropServices/Makefile [deleted file]
mcs/class/Facades/System.Private.CoreLib.InteropServices/System.Private.CoreLib.InteropServices-net_4_x.csproj [deleted file]
mcs/class/Facades/System.Private.CoreLib.InteropServices/System.Private.CoreLib.InteropServices.dll.sources [deleted file]
mcs/class/Facades/System.Private.CoreLib.InteropServices/TypeForwarders.cs [deleted file]
mcs/class/Facades/System.Reflection.Emit.ILGeneration/AssemblyInfo.cs
mcs/class/Facades/System.Reflection.Emit.Lightweight/AssemblyInfo.cs
mcs/class/Facades/System.Reflection.Emit/AssemblyInfo.cs
mcs/class/Facades/System.Reflection.TypeExtensions/TypeExtensions.CoreCLR.cs
mcs/class/Facades/System.Runtime.InteropServices/TypeForwarders.cs
mcs/class/Facades/System.Security.SecureString/SecureStringMarshal.cs
mcs/class/Facades/System.ServiceProcess.ServiceController/ServiceController_mobile.cs
mcs/class/Facades/System.ServiceProcess.ServiceController/TimeoutException_mobile.cs
mcs/class/Facades/System.Threading.AccessControl/ThreadingAclExtensions.cs
mcs/class/Facades/subdirs.make
mcs/class/Microsoft.Build/Test/Microsoft.Build.Construction/ProjectRootElementTest.cs
mcs/class/Microsoft.Build/Test/Microsoft.Build.Evaluation/ProjectCollectionTest.cs
mcs/class/Microsoft.Build/Test/Microsoft.Build.Evaluation/ToolsetTest.cs
mcs/class/Microsoft.Build/Test/Microsoft.Build.Execution/ProjectTargetInstanceTest.cs
mcs/class/Microsoft.Build/Test/Microsoft.Build.Execution/ProjectTaskInstanceTest.cs
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLite3.cs
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteBase.cs
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/UnsafeNativeMethods.cs
mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
mcs/class/Mono.Debugger.Soft/Test/dtest.cs
mcs/class/System.ComponentModel.DataAnnotations/Test/System.ComponentModel.DataAnnotations/CompareAttributeTest.cs
mcs/class/System.ComponentModel.DataAnnotations/Test/System.ComponentModel.DataAnnotations/CreditCardAttributeTest.cs
mcs/class/System.ComponentModel.DataAnnotations/Test/System.ComponentModel.DataAnnotations/EmailAddressAttributeTest.cs
mcs/class/System.ComponentModel.DataAnnotations/Test/System.ComponentModel.DataAnnotations/FileExtensionsAttributeTest.cs
mcs/class/System.ComponentModel.DataAnnotations/Test/System.ComponentModel.DataAnnotations/PhoneAttributeTest.cs
mcs/class/System.Core/common_System.Core.dll.sources
mcs/class/System.Core/net_4_x_System.Core.dll.sources
mcs/class/System.Data/System.Data.SqlClient/SqlDataReader.cs
mcs/class/System.Data/Test/System.Data.Common/DbDataReaderTest.cs
mcs/class/System.IdentityModel/Test/System.IdentityModel.Tokens/BootstrapContextTest.cs
mcs/class/System.Runtime.InteropServices.RuntimeInformation/Assembly/AssemblyInfo.cs
mcs/class/System.Security/System.Security.Cryptography.Pkcs/AlgorithmIdentifier.cs
mcs/class/System.Security/System.Security.Cryptography.Pkcs/ContentInfo.cs
mcs/class/System.Security/System.Security.Cryptography.Pkcs/EnvelopedCms.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/AddressHeader.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/AddressHeaderCollection.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/BindingContext.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/BindingElement.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/BindingElementCollection.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/ChannelBase.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/ChannelFactoryBase.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/CustomBinding.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/FaultConverter.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpRequestChannel.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpTransportBindingElement.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpsTransportBindingElement.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/Message.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageEncodingBindingElement.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageFault.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageHeader.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageHeaders.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageVersion.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/SecurityBindingElement.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/TcpTransportBindingElement.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/TransportBindingElement.cs
mcs/class/System.ServiceModel/System.ServiceModel.Description/ClientCredentials.cs
mcs/class/System.ServiceModel/System.ServiceModel.Description/IContractBehavior.cs
mcs/class/System.ServiceModel/System.ServiceModel.Description/IEndpointBehavior.cs
mcs/class/System.ServiceModel/System.ServiceModel.Description/IOperationBehavior.cs
mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/IClientMessageFormatter.cs
mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/IClientMessageInspector.cs
mcs/class/System.ServiceModel/System.ServiceModel.Security.Tokens/SecureConversationSecurityTokenParameters.cs
mcs/class/System.ServiceModel/System.ServiceModel/ActionNotSupportedException.cs
mcs/class/System.ServiceModel/System.ServiceModel/ChannelFactory.cs
mcs/class/System.ServiceModel/System.ServiceModel/ChannelFactory_1.cs
mcs/class/System.ServiceModel/System.ServiceModel/CommunicationException.cs
mcs/class/System.ServiceModel/System.ServiceModel/CommunicationObjectAbortedException.cs
mcs/class/System.ServiceModel/System.ServiceModel/CommunicationObjectFaultedException.cs
mcs/class/System.ServiceModel/System.ServiceModel/DnsEndpointIdentity.cs
mcs/class/System.ServiceModel/System.ServiceModel/DuplexClientBase.cs
mcs/class/System.ServiceModel/System.ServiceModel/EndpointAddress.cs
mcs/class/System.ServiceModel/System.ServiceModel/EndpointNotFoundException.cs
mcs/class/System.ServiceModel/System.ServiceModel/FaultCode.cs
mcs/class/System.ServiceModel/System.ServiceModel/FaultException.cs
mcs/class/System.ServiceModel/System.ServiceModel/InvalidMessageContractException.cs
mcs/class/System.ServiceModel/System.ServiceModel/MessageHeaderException.cs
mcs/class/System.ServiceModel/System.ServiceModel/MessageHeader_1.cs
mcs/class/System.ServiceModel/System.ServiceModel/ProtocolException.cs
mcs/class/System.ServiceModel/System.ServiceModel/QuotaExceededException.cs
mcs/class/System.ServiceModel/System.ServiceModel/ServerTooBusyException.cs
mcs/class/System.ServiceModel/System.ServiceModel/ServiceActivationException.cs
mcs/class/System.ServiceModel/System.ServiceModel/SpnEndpointIdentity.cs
mcs/class/System.ServiceModel/System.ServiceModel/UpnEndpointIdentity.cs
mcs/class/System.ServiceModel/Test/MetadataTests/ImportTests.cs
mcs/class/System.ServiceModel/Test/MetadataTests/MetadataSamples.cs
mcs/class/System.Threading.Tasks.Dataflow/Test/System.Threading.Tasks.Dataflow/TransformBlockTest.cs
mcs/class/System.Web/Test/System.Web.Security/MachineKeyTest.cs
mcs/class/System.Web/Test/System.Web.Security/MembershipPasswordAttributeTest.cs
mcs/class/System.Web/Test/System.Web/EventHandlerTaskAsyncHelperTest.cs
mcs/class/System.Web/Test/System.Web/HttpTaskAsyncHandlerTest.cs
mcs/class/System.Web/Test/System.Web/TaskAsyncResultTest.cs
mcs/class/System.XML/Test/System.Xml/XmlReaderCommonTests.cs
mcs/class/System.XML/Test/System.Xml/XmlReaderSettingsTests.cs
mcs/class/System.XML/Test/System.Xml/XmlResolverTest.cs
mcs/class/System.XML/Test/System.Xml/XmlSecureResolverTests.cs
mcs/class/System.XML/Test/System.Xml/XmlUrlResolverTests.cs
mcs/class/System.XML/Test/System.Xml/XmlWriterSettingsTests.cs
mcs/class/System.Xml.Linq/Test/System.Xml.Linq/XElementTest.cs
mcs/class/System/System.IO.Compression/DeflateStream.cs
mcs/class/System/System.IO.Compression/GZipStream.cs
mcs/class/System/System.Net.Sockets/Socket.cs
mcs/class/System/System.Net/HttpWebRequest.cs
mcs/class/System/System.Security.AccessControl/SemaphoreAccessRule.cs
mcs/class/System/System.Security.AccessControl/SemaphoreAuditRule.cs
mcs/class/System/System.Security.Cryptography.X509Certificates/X509KeyUsageExtension.cs
mcs/class/System/System.Security.Cryptography.X509Certificates/X509SubjectKeyIdentifierExtension.cs
mcs/class/System/Test/System.IO.Compression/DeflateStreamTest.cs
mcs/class/System/Test/System.IO.Compression/GzipStreamTest.cs
mcs/class/System/Test/System.Net.Sockets/SocketTest.cs
mcs/class/System/Test/System.Net.WebSockets/ClientWebSocketTest.cs
mcs/class/System/Test/System.Net/HttpWebRequestTest.cs
mcs/class/System/Test/System.Net/WebClientTest.cs
mcs/class/System/Test/System.Net/WebClientTestAsync.cs
mcs/class/System/Test/System/UriPermutationsTest.cs
mcs/class/System/Test/System/UriTest.cs
mcs/class/corlib/Microsoft.Win32/Win32RegistryApi.cs
mcs/class/corlib/Microsoft.Win32/Win32ResultCode.cs
mcs/class/corlib/Mono.Security/Uri.cs
mcs/class/corlib/Mono/RuntimeStructs.cs
mcs/class/corlib/ReferenceSources/AppContextSwitches.cs
mcs/class/corlib/System.Diagnostics/StackTrace.cs
mcs/class/corlib/System.Globalization/CultureInfo.cs
mcs/class/corlib/System.IO/DirectoryInfo.cs
mcs/class/corlib/System.IO/MonoIO.cs
mcs/class/corlib/System.IO/MonoIOError.cs
mcs/class/corlib/System.IO/Path.cs
mcs/class/corlib/System.Reflection.Emit/ConstructorBuilder.cs
mcs/class/corlib/System.Reflection.Emit/FieldBuilder.cs
mcs/class/corlib/System.Reflection.Emit/MethodBuilder.cs
mcs/class/corlib/System.Reflection.Emit/SignatureHelper.cs
mcs/class/corlib/System.Reflection.Emit/TypeBuilder.cs
mcs/class/corlib/System.Reflection.Emit/UnmanagedMarshal.cs
mcs/class/corlib/System.Reflection/AssemblyName.cs
mcs/class/corlib/System.Runtime.InteropServices/Marshal.cs
mcs/class/corlib/System.Runtime.InteropServices/SafeHandle.cs
mcs/class/corlib/System.Security.AccessControl/NativeObjectSecurity.cs
mcs/class/corlib/System.Security.Cryptography/CryptoConfig.common.cs [new file with mode: 0644]
mcs/class/corlib/System.Security.Cryptography/CryptoConfig.cs
mcs/class/corlib/System.Security.Cryptography/CryptoConfig.fullaot.cs
mcs/class/corlib/System.Security.Cryptography/CryptoConfig_2_1.cs [deleted file]
mcs/class/corlib/System.Security.Policy/Zone.cs
mcs/class/corlib/System.Text/Latin1Encoding.cs
mcs/class/corlib/System.Threading/EventWaitHandle.cs [deleted file]
mcs/class/corlib/System.Threading/NativeEventCalls.cs
mcs/class/corlib/System.Threading/Thread.cs
mcs/class/corlib/System/AppDomainSetup.cs
mcs/class/corlib/System/Environment.cs
mcs/class/corlib/System/TimeZoneInfo.cs
mcs/class/corlib/Test/Microsoft.Win32/RegistryKeyTest.cs
mcs/class/corlib/Test/System.Collections.Generic/ComparerTest.cs
mcs/class/corlib/Test/System.Globalization/CultureInfoTest.cs
mcs/class/corlib/Test/System.IO/DirectoryInfoTest.cs
mcs/class/corlib/Test/System.IO/FileInfoTest.cs
mcs/class/corlib/Test/System.IO/FileStreamTest.cs
mcs/class/corlib/Test/System.IO/MemoryStreamTest.cs
mcs/class/corlib/Test/System.IO/PathTest.cs
mcs/class/corlib/Test/System.IO/StreamReaderTest.cs
mcs/class/corlib/Test/System.IO/StreamTest.cs
mcs/class/corlib/Test/System.IO/StreamWriterTest.cs
mcs/class/corlib/Test/System.Reflection/AssemblyNameTest.cs
mcs/class/corlib/Test/System.Reflection/AssemblyTest.cs
mcs/class/corlib/Test/System.Reflection/IntrospectionExtensionsTest.cs
mcs/class/corlib/Test/System.Reflection/ModuleTest.cs
mcs/class/corlib/Test/System.Reflection/ParameterInfoTest.cs
mcs/class/corlib/Test/System.Reflection/PropertyInfoTest.cs
mcs/class/corlib/Test/System.Resources/ResourceReaderTest.cs
mcs/class/corlib/Test/System.Runtime.CompilerServices/AsyncVoidMethodBuilderTest.cs
mcs/class/corlib/Test/System.Runtime.CompilerServices/TaskAwaiterTest.cs
mcs/class/corlib/Test/System.Runtime.CompilerServices/TaskAwaiterTest_T.cs
mcs/class/corlib/Test/System.Runtime.CompilerServices/YieldAwaitableTest.cs
mcs/class/corlib/Test/System.Runtime.InteropServices/MarshalTest.cs
mcs/class/corlib/Test/System.Security.Claims/ClaimsIdentityTest.cs
mcs/class/corlib/Test/System.Security.Claims/ClaimsPrincipalTest.cs
mcs/class/corlib/Test/System.Security.Cryptography/CryptoConfigTest.cs
mcs/class/corlib/Test/System.Security.Cryptography/SignatureDescriptionTest.cs
mcs/class/corlib/Test/System.Security.Policy/ZoneTest.cs
mcs/class/corlib/Test/System.Text/ASCIIEncodingTest.cs
mcs/class/corlib/Test/System.Text/Latin1EncodingTest.cs [new file with mode: 0644]
mcs/class/corlib/Test/System.Threading.Tasks/ConcurrentExclusiveSchedulerPairTest.cs
mcs/class/corlib/Test/System.Threading.Tasks/TaskTest.cs
mcs/class/corlib/Test/System.Threading/CancellationTokenSourceTest.cs
mcs/class/corlib/Test/System.Threading/EventWaitHandleTest.cs
mcs/class/corlib/Test/System.Threading/ThreadTest.cs
mcs/class/corlib/Test/System.Threading/VolatileTest.cs
mcs/class/corlib/Test/System/AppDomainSetupTest.cs
mcs/class/corlib/Test/System/ArraySegmentTest.cs
mcs/class/corlib/Test/System/ConsoleTest.cs
mcs/class/corlib/Test/System/DelegateTest.cs
mcs/class/corlib/Test/System/DoubleTest.cs
mcs/class/corlib/Test/System/TimeZoneInfoTest.cs
mcs/class/corlib/Test/System/WeakReferenceTest.cs
mcs/class/corlib/coreclr/AsyncLocal.cs [deleted file]
mcs/class/corlib/coreclr/DisablePrivateReflectionAttribute.cs [deleted file]
mcs/class/corlib/coreclr/EncodingProvider.cs [deleted file]
mcs/class/corlib/coreclr/FormattableString.cs [deleted file]
mcs/class/corlib/coreclr/FormattableStringFactory.cs [deleted file]
mcs/class/corlib/coreclr/WaitHandleExtensions.cs [deleted file]
mcs/class/corlib/corlib.dll.sources
mcs/class/corlib/corlib_test.dll.sources
mcs/class/corlib/monotouch_runtime_corlib.dll.sources
mcs/class/corlib/monotouch_tv_corlib.dll.sources
mcs/class/corlib/monotouch_tv_runtime_corlib.dll.sources
mcs/class/corlib/monotouch_watch_corlib.dll.sources
mcs/class/corlib/monotouch_watch_runtime_corlib.dll.sources
mcs/class/dlr/Runtime/Microsoft.Scripting.Core/Actions/DynamicObject.cs
mcs/class/referencesource/System.Core/System/threading/ReaderWriterLockSlim/ReaderWriterLockSlim.cs
mcs/class/referencesource/System/sys/system/IO/ports/InternalResources.cs
mcs/class/referencesource/System/sys/system/threading/semaphore.cs
mcs/class/referencesource/mscorlib/system/runtime/interopservices/attributes.cs
mcs/class/referencesource/mscorlib/system/runtime/interopservices/dispatchwrapper.cs
mcs/class/referencesource/mscorlib/system/runtime/interopservices/errorwrapper.cs
mcs/class/referencesource/mscorlib/system/threading/eventwaithandle.cs
mcs/class/referencesource/mscorlib/system/threading/thread.cs
mcs/errors/cs0246-36.cs [new file with mode: 0644]
mcs/mcs/Makefile
mcs/mcs/anonymous.cs
mcs/mcs/assembly.cs
mcs/mcs/cs-tokenizer.cs
mcs/mcs/expression.cs
mcs/mcs/ikvm.cs
mcs/mcs/statement.cs
mcs/tests/dtest-065.cs [new file with mode: 0644]
mcs/tests/test-async-88.cs [new file with mode: 0644]
mcs/tests/test-async-89.cs [new file with mode: 0644]
mcs/tests/test-debug-30-ref.xml
mcs/tests/test-debug-30.cs
mcs/tests/ver-il-net_4_x.xml
mcs/tools/al/Al.cs
mcs/tools/corcompare/mono-api-info.cs
mcs/tools/linker/Mono.Linker.Steps/OutputStep.cs
mcs/tools/linker/Mono.Linker.Steps/ResolveFromXmlStep.cs
mcs/tools/linker/Mono.Linker.Steps/SweepStep.cs
mcs/tools/linker/Mono.Linker/AssemblyResolver.cs
mcs/tools/linker/Mono.Linker/LinkContext.cs
mcs/tools/mkbundle/mkbundle.cs
mcs/tools/mono-api-html/MemberComparer.cs
mcs/tools/mono-symbolicate/SymbolManager.cs
mcs/tools/mono-symbolicate/monosymbolicate.csproj
mcs/tools/tuner/Mono.Tuner/CecilRocks.cs
mcs/tools/xbuild/data/12.0/Microsoft.Common.targets
mcs/tools/xbuild/data/14.0/Microsoft.Common.targets
mcs/tools/xbuild/data/4.0/Microsoft.Common.targets
mono/io-layer/io.c
mono/io-layer/processes.h
mono/io-layer/wait.c
mono/io-layer/wait.h
mono/io-layer/wapi-remap.h
mono/metadata/Makefile.am
mono/metadata/appdomain.c
mono/metadata/assembly.c
mono/metadata/boehm-gc.c
mono/metadata/class-internals.h
mono/metadata/class.c
mono/metadata/custom-attrs-internals.h [new file with mode: 0644]
mono/metadata/custom-attrs.c [new file with mode: 0644]
mono/metadata/domain-internals.h
mono/metadata/domain.c
mono/metadata/dynamic-image-internals.h [new file with mode: 0644]
mono/metadata/dynamic-image.c [new file with mode: 0644]
mono/metadata/dynamic-stream-internals.h [new file with mode: 0644]
mono/metadata/dynamic-stream.c [new file with mode: 0644]
mono/metadata/file-io.c
mono/metadata/gc-internals.h
mono/metadata/gc.c
mono/metadata/handle.c
mono/metadata/handle.h
mono/metadata/icall-def.h
mono/metadata/icall.c
mono/metadata/jit-info.c
mono/metadata/lock-tracer.c
mono/metadata/marshal.c
mono/metadata/metadata.c
mono/metadata/metadata.h
mono/metadata/monitor.c
mono/metadata/mono-config.c
mono/metadata/mono-config.h
mono/metadata/mono-gc.h
mono/metadata/mono-perfcounters.c
mono/metadata/mono-security.c
mono/metadata/null-gc.c
mono/metadata/object-internals.h
mono/metadata/object.c
mono/metadata/profiler-private.h
mono/metadata/profiler.c
mono/metadata/profiler.h
mono/metadata/reflection-cache.h [new file with mode: 0644]
mono/metadata/reflection-internals.h
mono/metadata/reflection.c
mono/metadata/sgen-bridge-internals.h
mono/metadata/sgen-bridge.c
mono/metadata/sgen-bridge.h
mono/metadata/sgen-mono.c
mono/metadata/sgen-new-bridge.c
mono/metadata/sgen-old-bridge.c
mono/metadata/sgen-os-coop.c
mono/metadata/sgen-stw.c
mono/metadata/sgen-tarjan-bridge.c
mono/metadata/socket-io.c
mono/metadata/sre-encode.c [new file with mode: 0644]
mono/metadata/sre-internals.h [new file with mode: 0644]
mono/metadata/sre-save.c [new file with mode: 0644]
mono/metadata/sre.c [new file with mode: 0644]
mono/metadata/threadpool-ms.c
mono/metadata/threads-types.h
mono/metadata/threads.c
mono/metadata/verify.c
mono/mini/.gitignore
mono/mini/Makefile.am.in
mono/mini/alias-analysis.c
mono/mini/aot-compiler.c
mono/mini/aot-runtime.c
mono/mini/cpu-arm64.md
mono/mini/debugger-agent.c
mono/mini/decompose.c
mono/mini/driver.c
mono/mini/emitnunit.pl [deleted file]
mono/mini/jit-icalls.c
mono/mini/jit-icalls.h
mono/mini/local-propagation.c
mono/mini/main.c
mono/mini/method-to-ir.c
mono/mini/mini-amd64.c
mono/mini/mini-arm.c
mono/mini/mini-exceptions.c
mono/mini/mini-ia64.c
mono/mini/mini-llvm.c
mono/mini/mini-mips.c
mono/mini/mini-native-types.c
mono/mini/mini-ppc.c
mono/mini/mini-runtime.c
mono/mini/mini-s390x.c
mono/mini/mini-sparc.c
mono/mini/mini-windows-dllmain.c [new file with mode: 0644]
mono/mini/mini-x86.c
mono/mini/mini.h
mono/mini/tramp-arm.c
mono/profiler/decode.c
mono/profiler/proflog.c
mono/profiler/proflog.h
mono/profiler/utils.c
mono/sgen/sgen-marksweep.c
mono/tests/Makefile.am
mono/tests/TestingReferenceAssembly.cs [new file with mode: 0644]
mono/tests/TestingReferenceReferenceAssembly.cs [new file with mode: 0644]
mono/tests/abort-cctor.cs [new file with mode: 0644]
mono/tests/libtest.c
mono/tests/pinvoke2.cs
mono/tests/reference-loader.cs [new file with mode: 0644]
mono/tests/sgen-bridge-pathologies.cs
mono/unit-tests/test-conc-hashtable.c
mono/unit-tests/test-mono-linked-list-set.c
mono/utils/Makefile.am
mono/utils/atomic.h
mono/utils/hazard-pointer.c
mono/utils/hazard-pointer.h
mono/utils/lock-free-alloc.c
mono/utils/lock-free-queue.c
mono/utils/mono-compiler.h
mono/utils/mono-conc-hashtable.c
mono/utils/mono-hwcap-arm.c
mono/utils/mono-hwcap-arm.h [deleted file]
mono/utils/mono-hwcap-arm64.c
mono/utils/mono-hwcap-arm64.h [deleted file]
mono/utils/mono-hwcap-cross.c [new file with mode: 0644]
mono/utils/mono-hwcap-ia64.c
mono/utils/mono-hwcap-ia64.h [deleted file]
mono/utils/mono-hwcap-mips.c
mono/utils/mono-hwcap-mips.h [deleted file]
mono/utils/mono-hwcap-ppc.c
mono/utils/mono-hwcap-ppc.h [deleted file]
mono/utils/mono-hwcap-s390x.c
mono/utils/mono-hwcap-s390x.h [deleted file]
mono/utils/mono-hwcap-sparc.c
mono/utils/mono-hwcap-vars.h [new file with mode: 0644]
mono/utils/mono-hwcap-x86.c
mono/utils/mono-hwcap-x86.h [deleted file]
mono/utils/mono-hwcap.c
mono/utils/mono-hwcap.h
mono/utils/mono-linked-list-set.c
mono/utils/mono-linked-list-set.h
mono/utils/mono-log-common.c
mono/utils/mono-log-posix.c
mono/utils/mono-log-windows.c
mono/utils/mono-logger-internals.h
mono/utils/mono-logger.c
mono/utils/mono-logger.h
mono/utils/mono-membar.h
mono/utils/mono-proclib.c
mono/utils/mono-rand.c
mono/utils/mono-threads-posix.c
mono/utils/mono-threads-windows.c
mono/utils/mono-threads.c
mono/utils/mono-threads.h
mono/utils/w32handle.c
mono/utils/w32handle.h
msvc/libgcmonosgen.vcxproj
msvc/libgcmonosgen.vcxproj.filters
msvc/libmono-static.vcxproj
msvc/libmono-static.vcxproj.filters
msvc/libmono.vcxproj
msvc/libmono.vcxproj.filters
msvc/libmonoruntime.vcxproj
msvc/libmonoruntime.vcxproj.filters
msvc/mono-full-aot-compile-test.vcxproj
msvc/mono-full-aot-run-test.vcxproj
msvc/mono-mini-regression-test.vcxproj
msvc/mono-nunit-test.props [new file with mode: 0644]
msvc/mono-nunit-test.vcxproj [new file with mode: 0644]
msvc/mono-test-env.props
msvc/mono-testdriver-test.props [new file with mode: 0644]
msvc/mono-testdriver-test.vcxproj [new file with mode: 0644]
msvc/mono-testdriver-test.vcxproj.filters [new file with mode: 0644]
msvc/mono.props
msvc/mono.sln
msvc/mono.vcxproj
msvc/monodis.vcxproj
msvc/monograph.vcxproj
msvc/profiler-vtune.vcxproj
msvc/test-config-setup.bat [new file with mode: 0644]
msvc/test-invoke.vcxproj
msvc/test-metadata.vcxproj
msvc/teste.vcxproj
msvc/winsetup.bat
scripts/ci/run-jenkins.sh
scripts/ci/run-test-profiler-stress-tests.sh [new file with mode: 0755]

index 522cb36c9ea47999dfd6dbe7474f11567a1aa1b8..c03adcc0c45f20f7be507986a6ddd4437ccfdb9b 100644 (file)
@@ -1,4 +1,5 @@
 ACCEPTANCE_TESTS_PATH=external
+BENCHMARKER_PATH=$(ACCEPTANCE_TESTS_PATH)/benchmarker
 ROSLYN_PATH=$(ACCEPTANCE_TESTS_PATH)/roslyn
 CORECLR_PATH=$(ACCEPTANCE_TESTS_PATH)/coreclr
 MSTESTSUITE_PATH=$(ACCEPTANCE_TESTS_PATH)/ms-test-suite
@@ -14,10 +15,11 @@ MCS = $(RUNTIME) $(mcs_topdir)/class/lib/build/mcs.exe
 ILASM = $(RUNTIME) $(CLASS)/ilasm.exe
 
 include versions.mk
+include profiler-stress.mk
 include roslyn.mk
 include coreclr.mk
 include ms-test-suite.mk
 
-check-full: check-roslyn check-coreclr check-ms-test-suite
+check-full: check-profiler-stress check-roslyn check-coreclr check-ms-test-suite
 
 clean-local: clean-local-coreclr
index 8287c176abcc939d505a19034ebe3baa7411df2b..01faee39c981b1215ef68e84e38aa97446d09c14 100644 (file)
   {
     "name": "ms-test-suite", 
     "url": "git@github.com:xamarin/ms-test-suite.git", 
-    "rev": "bcd16462b0b427c582c2b4c81846a42d7ccd527f", 
+    "rev": "eb7cd709549bffe170653a50805f1593d66ea81e", 
     "remote-branch": "origin/master", 
     "branch": "master", 
     "directory": "ms-test-suite"
+  }, 
+  {
+    "name": "benchmarker", 
+    "url": "git://github.com/xamarin/benchmarker.git", 
+    "rev": "97f618cd585af549dd861b7c142656c496f6a89b", 
+    "remote-branch": "origin/master", 
+    "branch": "master", 
+    "directory": "benchmarker"
   }
 ]
diff --git a/acceptance-tests/profiler-stress.mk b/acceptance-tests/profiler-stress.mk
new file mode 100644 (file)
index 0000000..9188b17
--- /dev/null
@@ -0,0 +1,12 @@
+SYS_REFS = \
+       System.dll \
+       System.Core.dll \
+       System.Data.dll \
+       System.Runtime.Serialization.dll \
+       System.Xml.dll \
+       System.Xml.Linq.dll
+
+check-profiler-stress:
+       @$(MAKE) validate-benchmarker RESET_VERSIONS=1
+       cd profiler-stress && $(MCS) -target:exe $(addprefix -r:, $(SYS_REFS)) -out:runner.exe @runner.exe.sources
+       cd profiler-stress && $(RUNTIME) runner.exe
diff --git a/acceptance-tests/profiler-stress/runner.cs b/acceptance-tests/profiler-stress/runner.cs
new file mode 100644 (file)
index 0000000..b2638c1
--- /dev/null
@@ -0,0 +1,108 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using Newtonsoft.Json;
+
+// Shut up CLS compliance warnings from Json.NET.
+[assembly: CLSCompliant (true)]
+
+namespace Mono.Profiling.Tests.Stress {
+
+       // https://github.com/xamarin/benchmarker/blob/master/tools/libdbmodel/Benchmark.cs
+       class Benchmark {
+               public string Name { get; set; }
+               public string TestDirectory { get; set; }
+               public bool OnlyExplicit { get; set; }
+               public string[] CommandLine { get; set; }
+               public string[] ClientCommandLine { get; set; }
+               public string[] AOTAssemblies { get; set; }
+
+               public static Benchmark Load (string file)
+               {
+                       return JsonConvert.DeserializeObject<Benchmark> (File.ReadAllText (file));
+               }
+       }
+
+       static class Program {
+
+               static int Main ()
+               {
+                       var depDir = Path.Combine ("..", "external", "benchmarker");
+                       var benchDir = Path.Combine (depDir, "benchmarks");
+                       var testDir = Path.Combine (depDir, "tests");
+
+                       var benchmarks = Directory.EnumerateFiles (benchDir, "*.benchmark")
+                                        .Select (Benchmark.Load)
+                                        .Where (b => !b.OnlyExplicit && b.ClientCommandLine == null)
+                                        .OrderBy (b => b.Name)
+                                        .ToArray ();
+
+                       var monoPath = Path.GetFullPath (Path.Combine ("..", "..", "runtime", "mono-wrapper"));
+                       var classDir = Path.GetFullPath (Path.Combine ("..", "..", "mcs", "class", "lib", "net_4_x"));
+
+                       var rand = new Random ();
+                       var cpus = Environment.ProcessorCount;
+
+                       var successes = 0;
+                       var failures = 0;
+
+                       var sw = Stopwatch.StartNew ();
+
+                       for (var i = 0; i < benchmarks.Length; i++) {
+                               var bench = benchmarks [i];
+
+                               var sampleFreq = rand.Next (0, 1001);
+                               var sampleMode = rand.Next (0, 2) == 1 ? "real" : "process";
+                               var maxSamples = rand.Next (0, cpus * 2000 + 1);
+                               var heapShotFreq = rand.Next (0, 11);
+                               var maxFrames = rand.Next (0, 33);
+                               var allocMode = rand.Next (0, 2) == 1 ? "alloc" : "noalloc";
+
+                               var profOptions = $"sample=cycles/{sampleFreq},sampling-{sampleMode},maxsamples={maxSamples},heapshot={heapShotFreq}gc,maxframes={maxFrames},{allocMode},output=/dev/null";
+
+                               var info = new ProcessStartInfo {
+                                       UseShellExecute = false,
+                                       WorkingDirectory = Path.Combine (testDir, bench.TestDirectory),
+                                       FileName = monoPath,
+                                       Arguments = $"--debug --profile=log:{profOptions} " + string.Join (" ", bench.CommandLine),
+                               };
+
+                               info.EnvironmentVariables.Clear ();
+                               info.EnvironmentVariables.Add ("MONO_PATH", classDir);
+
+                               var progress = $"({i + 1}/{benchmarks.Length})";
+
+                               Console.ForegroundColor = ConsoleColor.Blue;
+                               Console.WriteLine ($"[{sw.Elapsed.ToString ("G")}] {progress} Running {bench.Name} with profiler options: {profOptions}");
+                               Console.ResetColor ();
+
+                               var sw2 = Stopwatch.StartNew ();
+
+                               using (var proc = Process.Start (info)) {
+                                       proc.WaitForExit ();
+                                       sw2.Stop ();
+
+                                       Console.WriteLine ();
+
+                                       if (proc.ExitCode != 0)
+                                               failures++;
+                                       else
+                                               successes++;
+
+                                       Console.ForegroundColor = proc.ExitCode != 0 ? ConsoleColor.Red : ConsoleColor.Green;
+                                       Console.WriteLine ($"[{sw.Elapsed.ToString ("G")}] {progress} {bench.Name} took {sw2.Elapsed.ToString ("G")} and exited with code: {proc.ExitCode}");
+                                       Console.ResetColor ();
+                               }
+                       }
+
+                       sw.Stop ();
+
+                       Console.ForegroundColor = failures != 0 ? ConsoleColor.Red : ConsoleColor.Green;
+                       Console.WriteLine ($"[{sw.Elapsed.ToString ("G")}] Finished with {successes}/{benchmarks.Length} passing tests");
+                       Console.ResetColor ();
+
+                       return failures;
+               }
+       }
+}
diff --git a/acceptance-tests/profiler-stress/runner.exe.sources b/acceptance-tests/profiler-stress/runner.exe.sources
new file mode 100644 (file)
index 0000000..fc734ed
--- /dev/null
@@ -0,0 +1,156 @@
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonBinaryType.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonBinaryWriter.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonReader.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonToken.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonType.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonWriter.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonObjectId.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/BinaryConverter.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/DataSetConverter.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/DataTableConverter.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/CustomCreationConverter.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/DateTimeConverterBase.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/EntityKeyMemberConverter.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/ExpandoObjectConverter.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/KeyValuePairConverter.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/BsonObjectIdConverter.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/RegexConverter.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/StringEnumConverter.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/ConstructorHandling.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/VersionConverter.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/DateFormatHandling.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/DateTimeZoneHandling.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Formatting.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConstructorAttribute.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonPosition.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JPropertyKeyedCollection.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicProxy.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JPath.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JRaw.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Required.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonDynamicContract.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonFormatterConverter.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonISerializableContract.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonLinqContract.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonPrimitiveContract.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DynamicValueProvider.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ErrorEventArgs.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JPropertyDescriptor.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DefaultReferenceResolver.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/PreserveReferencesHandling.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/IJsonLineInfo.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonArrayAttribute.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonContainerAttribute.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/DefaultValueHandling.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConverterAttribute.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonObjectAttribute.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonSerializerSettings.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonValidatingReader.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/IJEnumerable.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenEqualityComparer.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/MemberSerialization.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/ObjectCreationHandling.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/IsoDateTimeConverter.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonTextReader.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonPropertyAttribute.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonIgnoreAttribute.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonTextWriter.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonWriterException.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonReaderException.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConverter.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConverterCollection.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonReader.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConvert.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonSerializationException.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonSerializer.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/Extensions.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JConstructor.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JContainer.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JEnumerable.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JObject.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JArray.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenReader.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenWriter.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JToken.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JProperty.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenType.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JValue.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/Extensions.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaException.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaModel.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaModelBuilder.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaNodeCollection.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaNode.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaResolver.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaWriter.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/UndefinedSchemaIdHandling.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/ValidationEventArgs.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/ValidationEventHandler.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/CamelCasePropertyNamesContractResolver.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DefaultSerializationBinder.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ErrorContext.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/IContractResolver.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/IValueProvider.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonContract.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonProperty.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonPropertyCollection.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/MissingMemberHandling.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/NullValueHandling.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/ReferenceLoopHandling.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchema.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaBuilder.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaConstants.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/IReferenceResolver.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaType.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalBase.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerProxy.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonStringContract.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/CachedAttributeGetter.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/LateBoundMetadataTypeAttribute.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ReflectionValueProvider.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/OnErrorAttribute.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/Base64Encoder.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicProxyMetaObject.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicUtils.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicWrapper.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ObjectConstructor.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ILGeneratorExtensions.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ReflectionDelegateFactory.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/LateBoundReflectionDelegateFactory.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/MethodCall.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/StringReference.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ThreadSafeStore.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/TypeNameHandling.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/BidirectionalDictionary.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/CollectionWrapper.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DateTimeUtils.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DictionaryWrapper.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/EnumUtils.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/EnumValue.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/EnumValues.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/JavaScriptUtils.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonToken.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonWriter.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/StringBuffer.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ListWrapper.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/MathUtils.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/MiscellaneousUtils.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/StringUtils.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/TypeExtensions.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ValidationUtils.cs
+../../external/Newtonsoft.Json/Src/Newtonsoft.Json/WriteState.cs
+runner.cs
index 84b4f85c6cdc1dd693b8a41f339693b0fb73fecf..0c070a0f11462278e44c1b024c2e2408e92bc375 100644 (file)
@@ -3,28 +3,35 @@
 SUBMODULES_CONFIG_FILE = $(top_srcdir)/acceptance-tests/SUBMODULES.json
 include $(top_srcdir)/scripts/submodules/versions.mk
 
+$(eval $(call ValidateVersionTemplate,benchmarker,BENCHMARKER))
 $(eval $(call ValidateVersionTemplate,roslyn,ROSLYN))
 $(eval $(call ValidateVersionTemplate,coreclr,CORECLR))
 $(eval $(call ValidateVersionTemplate,ms-test-suite,MSTESTSUITE))
 
 # Bump the given submodule to the revision given by the REV make variable
 # If COMMIT is 1, commit the change
+bump-benchmarker: __bump-benchmarker
 bump-roslyn: __bump-version-roslyn
 bump-coreclr: __bump-version-coreclr
 bump-ms-test-suite: __bump-version-ms-test-suite
 
 # Bump the given submodule to the branch given by the BRANCH/REMOTE_BRANCH make variables
 # If COMMIT is 1, commit the change
+bump-branch-benchmarker: __bump-branch-benchmarker
 bump-branch-roslyn: __bump-branch-roslyn
 bump-branch-coreclr: __bump-branch-coreclr
 bump-branch-ms-test-suite: __bump-branch-ms-test-suite
 
 # Bump the given submodule to its current GIT version
 # If COMMIT is 1, commit the change
+bump-current-benchmarker: __bump-current-benchmarker
 bump-current-roslyn: __bump-current-version-roslyn
 bump-current-coreclr: __bump-current-version-coreclr
 bump-current-ms-test-suite: __bump-current-version-ms-test-suite
 
+commit-bump-benchmarker:
+       $(MAKE) bump-benchmarker COMMIT=1
+
 commit-bump-roslyn:
        $(MAKE) bump-roslyn COMMIT=1
 
@@ -34,6 +41,9 @@ commit-bump-coreclr:
 commit-bump-ms-test-suite:
        $(MAKE) bump-ms-test-suite COMMIT=1
 
+commit-bump-current-benchmarker:
+       $(MAKE) bump-current-benchmarker COMMIT=1
+
 commit-bump-current-roslyn:
        $(MAKE) bump-current-roslyn COMMIT=1
 
index 924acc99cdbbc681fa194f859aa9fc50b36e8dea..21db9420c474e44b3e974d7e4b150795ea41094e 100644 (file)
@@ -2856,13 +2856,12 @@ if test "x$enable_llvm" = "xyes"; then
    LLVM_SYSTEM_LIBS=`$LLVM_CONFIG --system-libs 2>/dev/null | grep -- -`
    llvm_jit_supported=yes
    llvm_jit_libs="jit mcjit $llvm_codegen"
-   if test $llvm_api_version -gt 100; then
-         # Based on llvm 3.9, only aot is currently supported
-      llvm_jit_libs="orcjit $llvm_codegen"
-   elif test "x$host" != "x$target"; then
+   if test "x$host" != "x$target"; then
       # No need for jit libs
          llvm_jit_supported=no
       llvm_jit_libs=""
+   elif test $llvm_api_version -gt 100; then
+      llvm_jit_libs="orcjit $llvm_codegen"
    fi
    LLVM_LIBS=`$LLVM_CONFIG --libs analysis core bitwriter $llvm_jit_libs`
    if test "x$LLVM_LIBS" = "x"; then
index 20d6cb9dc9b3566f7408862163ea6c0c98b30666..cddef0364cbfe34fa2f3fff6e0191d55853c9267 100644 (file)
@@ -40,9 +40,8 @@
        <p>The output of the SCC analysis is passed to the
        `cross_references()` callback.  It is expected to set the
        `is_alive` flag on those strongly connected components that it
-       wishes to be kept alive.  Only bridged objects will be
-       reported to the callback, i.e., non-bridged objects are
-       removed from the callback graph.
+       wishes to be kept alive.  The value of `is_alive` will be
+       ignored on any SCCs which lack bridges.
        
        <p>In monodroid each bridged object has a corresponding Java
        mirror object.  In the bridge callback it reifies the Mono
@@ -63,7 +62,7 @@
 
 <div class="mapi-header">
 enum {
-        SGEN_BRIDGE_VERSION = 4
+        SGEN_BRIDGE_VERSION = 5
 };
         
 typedef enum {
index 9486aff07e3e7fbb7c26cadf328bff24b7bd3b2a..5baec653c336451d8c9075dd76f69c233d4f9da3 100644 (file)
@@ -30,6 +30,9 @@
 #include <glib.h>
 
 #include <windows.h>
+#ifdef _MSC_VER
+#include <shlobj.h>
+#endif
 #include <direct.h>
 #include <io.h>
 
@@ -116,20 +119,34 @@ g_path_is_absolute (const char *filename)
 const gchar *
 g_get_home_dir (void)
 {
-       /* FIXME */
-       const gchar *drive = g_getenv ("HOMEDRIVE");
-       const gchar *path = g_getenv ("HOMEPATH");
        gchar *home_dir = NULL;
-       
-       if (drive && path) {
-               home_dir = g_malloc(strlen(drive) + strlen(path) +1);
-               if (home_dir) {
-                       sprintf(home_dir, "%s%s", drive, path);
-               }
+
+#ifdef _MSC_VER
+       PWSTR profile_path = NULL;
+       HRESULT hr = SHGetKnownFolderPath (&FOLDERID_Profile, KF_FLAG_DEFAULT, NULL, &profile_path);
+       if (SUCCEEDED(hr)) {
+               home_dir = u16to8 (profile_path);
+               CoTaskMemFree (profile_path);
+       }
+#endif
+
+       if (!home_dir) {
+               home_dir = (gchar *) g_getenv ("USERPROFILE");
        }
 
-       g_free (drive);
-       g_free (path);
+       if (!home_dir) {
+               const gchar *drive = g_getenv ("HOMEDRIVE");
+               const gchar *path = g_getenv ("HOMEPATH");
+
+               if (drive && path) {
+                       home_dir = g_malloc (strlen (drive) + strlen (path) + 1);
+                       if (home_dir) {
+                               sprintf (home_dir, "%s%s", drive, path);
+                       }
+               }
+               g_free (drive);
+               g_free (path);
+       }
 
        return home_dir;
 }
index ea18396c86ab3f8ba5d0fcd9ada9e066bd4f9f92..f38c0f5d99b6e44fa906d14e1146fa65a3806cd3 160000 (submodule)
@@ -1 +1 @@
-Subproject commit ea18396c86ab3f8ba5d0fcd9ada9e066bd4f9f92
+Subproject commit f38c0f5d99b6e44fa906d14e1146fa65a3806cd3
index e7929918ad0bb9df8d12b07a7803f660a8a3244f..7b1460a888ae20f5756aa3e8ad71781094541ffd 100644 (file)
@@ -93,6 +93,7 @@ GC_API GC_PTR (*GC_oom_fn) GC_PROTO((size_t bytes_requested));
                        /* pointer to a previously allocated heap       */
                        /* object.                                      */
 
+// Keep somewhat in sync with mono/metadata/profiler.h:enum MonoGCEvent
 typedef enum {
        GC_EVENT_START,
        GC_EVENT_MARK_START,
index de2b6ac7c3ff22a480831f8a10292f0846749835..0c8b29892ff5f582e121af6d36c300073815cdb5 100644 (file)
@@ -2,6 +2,7 @@ man_MANS = \
        al.1                  \
        cert2spc.1            \
        certmgr.1             \
+       cert-sync.1           \
        chktrust.1            \
        cilc.1                \
        crlupdate.1           \
diff --git a/man/cert-sync.1 b/man/cert-sync.1
new file mode 100644 (file)
index 0000000..66d3d60
--- /dev/null
@@ -0,0 +1,52 @@
+.\" 
+.\" cert-sync  manual page.
+.\" Copyright 2016 Microsoft Corp
+.\" Author:
+.\"   Jo Shields <joshield@microsoft.com>
+.\"
+.TH Mono "cert-sync"
+.SH NAME
+cert-sync \- Mono Certificate Store Sync Tool
+.SH SYNOPSIS
+.PP
+.B cert-sync [--quiet] [--user] filename
+.SH DESCRIPTION
+This tool allows you to populate a Mono certificate store, from a large 
+concatenated list of certificates in PEM format (commonly provided on most 
+Linux distributions).
+
+Its use is intended to be automated at Mono install time, by distribution 
+packagers, to seamlessly provide SSL support to Mono applications without 
+further user interaction.
+.SH OPTIONS
+.TP
+.I "--quiet"
+Suppress verbose output
+.TP
+.I "--user"
+Populate the per-user store in the user's home directory, instead of the 
+system-wide store.
+.TP
+.I "filename.crt"
+Path to a certificate bundle. The Mono store will have any extra entries 
+removed, and new entries added, to reflect the provided file.
+
+.SH EXAMPLES
+.TP
+.B cert-sync /etc/ssl/certs/ca-certificates.crt
+Synchronize the machine store, from the Debian cert store location
+.TP
+.B cert-sync --user /etc/pki/tls/certs/ca-bundle.crt
+Synchronize the user store, from the Red Hat cert store location
+
+.SH AUTHOR
+Written by Jo Shields
+
+.SH COPYRIGHT
+Copyright (C) 2016 Microsoft Corp
+.SH MAILING LISTS
+Visit http://lists.ximian.com/mailman/listinfo/mono-list for details.
+.SH WEB SITE
+Visit http://www.mono-project.com for details
+.SH SEE ALSO
+.BR certmgr(1)
index 160786d94f6a2643fba63837e3f12cdc5826658b..95861e0aeab8e58ebbaaf64c8758ffe813b0f818 100644 (file)
@@ -40,6 +40,16 @@ command:
        $ mkbundle -o hello --simple hello.exe
 
 .fi
+.PP
+You can configure options to be passed to the Mono runtime directly
+into your executable, for this, use the 
+.I --options
+flag.  For example, the following disables inlining, by passing the
+"-O=-inline" command line option to the embedded executable:
+.nf
+
+       $ mkbundle -o hello --options -O=-inline --simple hello.exe
+
 .PP
 The simple version allows for cross-compiling, this requires a Mono
 runtime to be installed in the ~/.mono/targets/TARGET/mono to be
@@ -119,6 +129,12 @@ This option will bundle all of the referenced assemblies for the
 assemblies listed on the command line option.  This is useful to
 distribute a self-contained image.
 .TP
+.I "--env KEY=VALUE"
+Use this to hardcode an environment variable at runtime for KEY to be
+mapped to VALUE.   This is useful in scenarios where you want to
+enable certain Mono runtime configuration options that are controlled
+by environment variables.
+.TP
 .I "--fetch-target target"
 Downloads a precompiled runtime for the specified target from the Mono
 distribution site.
@@ -167,6 +183,22 @@ image created.
 Places the output on `out'.  If the flag -c is specified, this is the
 C host program.  If not, this contains the resulting executable.
 .TP
+.I "--options OPTS"
+Since the resulting executable will be treated as a standalone
+program, you can use this option to pass configuration options to the
+Mono runtime and bake those into the resulting executable.  These
+options are specified as 
+.I OPTS.
+.Sp
+You can use the above to configure options that you would typically
+pass on the command line to Mono, before the main program is
+executed.   
+.Sp
+Additionally, users of your binary can still configure their own
+options by setting the 
+.I MONO_ENV_OPTIONS
+environment variable.   
+.TP
 .I "--target-server SERVER"
 By default the mkbundle tool will download from a Mono server the
 target runtimes, you can specify a different server to provide
index af61efa37cb84a91b735581972a4f8dec8565285..c4fd545dd104c5413ea6a5bcb627a25bccf6fec1 100644 (file)
@@ -1,4 +1,8 @@
-.TH mprof-report 1 "" 
+.de Sp
+.if t .sp .5v
+.if n .sp
+..
+.TH mprof-report 1 ""
 .SH The Mono log profiler
 .PP
 The Mono \f[I]log\f[] profiler can be used to collect a lot of
@@ -139,8 +143,8 @@ to the control port
 program behaviour.
 The default is to collect a 100 times per second (100 Hz) the
 instruction pointer.
-This is equivalent to the value \[lq]cycles/100\[rq] for
-\f[I]TYPE\f[].
+This is equivalent to the value \[lq]cycles/100\[rq].
+A value of zero for \f[I]FREQ\f[] effectively disables sampling.
 On some systems, like with recent Linux kernels, it is possible to
 cause the sampling to happen for other events provided by the
 performance counters of the cpu.
@@ -237,6 +241,9 @@ Methods JITted using mono JIT, Methods JITted using LLVM, Total time
 spent JITting (sec), User Time, System Time, Total Time, Working Set,
 Private Bytes, Virtual Bytes, Page Faults and CPU Load Average (1min,
 5min and 15min).
+.IP \[bu] 2
+\f[I]coverage\f[]: collect code coverage data. This implies enabling
+the \f[I]calls\f[] option.
 .RE
 .SS Analyzing the profile data
 .PP
@@ -260,7 +267,7 @@ To see this info invoke mprof-report as follows:
 \f[B]mprof-report\ --traces\ output.mlpd\f[]
 .PP
 The maximum number of methods in each stack trace can be specified
-with the \f[I]\[em]maxframes=NUM\f[] option:
+with the \f[I]--maxframes=NUM\f[] option:
 .PP
 \f[B]mprof-report\ --traces\ --maxframes=4\ output.mlpd\f[]
 .PP
@@ -272,7 +279,7 @@ specific events when the \f[I]nocalls\f[] option is used, so in
 that case, if more stack frames are required in mprof-report, a
 bigger value for maxframes when profiling must be used, too.
 .PP
-The \f[I]\[em]traces\f[] option also controls the reverse reference
+The \f[I]--traces\f[] option also controls the reverse reference
 feature in the heapshot report: for each class it reports how many
 references to objects of that class come from other classes.
 .SS Sort order for methods and allocations
@@ -362,6 +369,10 @@ version
 \f[I]heapshot\f[]: live heap usage at heap shots
 .IP \[bu] 2
 \f[I]counters\f[]: counters samples
+.IP \[bu] 2
+\f[I]coverage\f[]: code coverage data
+.IP \[bu] 2
+\f[I]stats\f[]: event statistics
 .PP
 It is possible to limit some of the data displayed to a timeframe
 of the program execution with the option:
@@ -391,23 +402,23 @@ Instead of printing the usual reports from the profiler data, it is
 possible to track some interesting information about some specific
 object addresses.
 The objects are selected based on their address with the
-\f[I]\[em]track\f[] option as follows:
+\f[I]--track\f[] option as follows:
 .PP
 \f[B]--track=0xaddr1[,0xaddr2,...]\f[]
 .PP
 The reported info (if available in the data file), will be class
 name, size, creation time, stack trace of creation (with the
-\f[I]\[em]traces\f[] option), etc.
+\f[I]--traces\f[] option), etc.
 If heapshot data is available it will be possible to also track
 what other objects reference one of the listed addresses.
 .PP
 The object addresses can be gathered either from the profiler
 report in some cases (like in the monitor lock report), from the
 live application or they can be selected with the
-\f[I]\[em]find=FINDSPEC\f[] option.
+\f[I]--find=FINDSPEC\f[] option.
 FINDSPEC can be one of the following:
 .IP \[bu] 2
-\f[I]S:SIZE\f[]: where the object is selected if it's size is at
+\f[I]S:SIZE\f[]: where the object is selected if its size is at
 least \f[I]SIZE\f[]
 .IP \[bu] 2
 \f[I]T:NAME\f[]: where the object is selected if \f[I]NAME\f[]
@@ -432,6 +443,13 @@ By default mprof-report will print the summary data to the console.
 To print it to a file, instead, use the option:
 .PP
 \f[B]--out=FILENAME\f[]
+.SS Processing code coverage data
+.PP
+If you ran the profiler with the \f[I]coverage\f[] option, you can
+process the collected coverage data into an XML file by running
+mprof-report like this:
+.PP
+\f[B]mprof-report --coverage-out=coverage.xml output.mlpd\f[]
 .SS Dealing with profiler slowness
 .PP
 If the profiler needs to collect lots of data, the execution of the
@@ -439,20 +457,20 @@ program will slow down significantly, usually 10 to 20 times
 slower.
 There are several ways to reduce the impact of the profiler on the
 program execution.
-.SS Use the statistical sampling mode
-.PP
+.IP "\f[I]Use the statistical sampling mode\f[]" 4
+.Sp
 Statistical sampling allows executing a program under the profiler
 with minimal performance overhead (usually less than 10%).
 This mode allows checking where the program is spending most of
-it's execution time without significantly perturbing its behaviour.
-.SS Collect less data
-.PP
+its execution time without significantly perturbing its behaviour.
+.IP "\f[I]Collect less data\f[]" 4
+.Sp
 Collecting method enter/leave events can be very expensive,
 especially in programs that perform many millions of tiny calls.
 The profiler option \f[I]nocalls\f[] can be used to avoid
 collecting this data or it can be limited to only a few call levels
 with the \f[I]calldepth\f[] option.
-.PP
+.Sp
 Object allocation information is expensive as well, though much
 less than method enter/leave events.
 If it's not needed, it can be skipped with the \f[I]noalloc\f[]
@@ -463,14 +481,14 @@ expensive as well.
 The impact of stack trace information can be reduced by setting a
 low value with the \f[I]maxframes\f[] option or by eliminating them
 completely, by setting it to 0.
-.PP
-The other major source of data is the heapshot profiler option:
-especially if the managed heap is big, since every object needs to
-be inspected.
+.Sp
+The other major source of data is the \f[I]heapshot\f[] profiler
+option: especially if the managed heap is big, since every object
+needs to be inspected.
 The \f[I]MODE\f[] parameter of the \f[I]heapshot\f[] option can be
 used to reduce the frequency of the heap shots.
-.SS Reduce the timestamp overhead
-.PP
+.IP "\f[I]Reduce the timestamp overhead\f[]" 4
+.Sp
 On many operating systems or architectures what actually slows down
 profiling is the function provided by the system to get timestamp
 information.
@@ -486,15 +504,15 @@ There are a few ways to minimize the amount of data, for example by
 not collecting some of the more space-consuming information or by
 compressing the information on the fly or by just generating a
 summary report.
-.SS Reducing the amount of data
-.PP
+.IP "\f[I]Reducing the amount of data\f[]" 4
+.Sp
 Method enter/leave events can be excluded completely with the
 \f[I]nocalls\f[] option or they can be limited to just a few levels
 of calls with the \f[I]calldepth\f[] option.
 For example, the option:
-.PP
+.Sp
 \f[B]calldepth=10\f[]
-.PP
+.Sp
 will ignore the method events when there are more than 10 managed
 stack frames.
 This is very useful for programs that have deep recursion or for
@@ -503,59 +521,59 @@ the call stack.
 The optimal number for the calldepth option depends on the program
 and it needs to be balanced between providing enough profiling
 information and allowing fast execution speed.
-.PP
+.Sp
 Note that by default, if method events are not recorded at all, the
 profiler will collect stack trace information at events like
 allocations.
 To avoid gathering this data, use the \f[I]maxframes=0\f[] profiler
 option.
-.PP
+.Sp
 Allocation events can be eliminated with the \f[I]noalloc\f[]
 option.
-.PP
+.Sp
 Heap shot data can also be huge: by default it is collected at each
 major collection.
 To reduce the frequency, you can specify a heapshot mode: for
 example to collect every 5 collections (including major and minor):
-.PP
+.Sp
 \f[B]heapshot=5gc\f[]
-.PP
+.Sp
 or when at least 5 seconds passed since the last heap shot:
-.PP
+.Sp
 \f[B]heapshot=5000ms\f[]
-.SS Compressing the data
-.PP
+.IP "\f[I]Compressing the data\f[]" 4
+.Sp
 To reduce the amout of disk space used by the data, the data can be
 compressed either after it has been generated with the gzip
 command:
-.PP
+.Sp
 \f[B]gzip\ -9\ output.mlpd\f[]
-.PP
+.Sp
 or it can be compressed automatically by using the \f[I]zip\f[]
 profiler option.
 Note that in this case there could be a significant slowdown of the
 profiled program.
-.PP
+.Sp
 The mprof-report program will tranparently deal with either
 compressed or uncompressed data files.
-.SS Generating only a summary report
-.PP
+.IP "\f[I]Generating only a summary report\f[]" 4
+.Sp
 Often it's enough to look at the profiler summary report to
 diagnose an issue and in this case it's possible to avoid saving
 the profiler data file to disk.
 This can be accomplished with the \f[I]report\f[] profiler option,
 which will basically send the data to the mprof-report program for
 display.
-.PP
+.Sp
 To have more control of what summary information is reported (or to
 use a completely different program to decode the profiler data),
 the \f[I]output\f[] profiler option can be used, with \f[B]|\f[] as
 the first character: the rest of the output name will be executed
 as a program with the data fed in on the standard input.
-.PP
+.Sp
 For example, to print only the Monitor summary with stack trace
 information, you could use it like this:
-.PP
+.Sp
 \f[B]output=|mprof-report\ --reports=monitor\ --traces\ -\f[]
 .SH WEB SITE
 http://www.mono-project.com/docs/debug+profile/profile/profiler/
@@ -563,5 +581,4 @@ http://www.mono-project.com/docs/debug+profile/profile/profiler/
 .PP
 mono(1)
 .SH AUTHORS
-Paolo Molaro.
-
+Paolo Molaro, Alex Rønne Petersen
index 16d3a64b65ef2890025c644210a2fbaa7fb7ab6b..749b5a0faf4edbd8d29eb176582e397ec64db32c 100644 (file)
@@ -123,12 +123,20 @@ TEST_HARNESS_POSTPROC_ONDOTNET = (echo ''; cat TestResult-ondotnet-$(PROFILE).lo
 endif
 
 ifdef FIXTURE
+ifdef NUNIT_LITE
+FIXTURE_ARG = -test=MonoTests.$(FIXTURE)
+else
 FIXTURE_ARG = -fixture=MonoTests.$(FIXTURE)
 endif
+endif
 
 ifdef TESTNAME
+ifdef NUNIT_LITE
+TESTNAME_ARG = -test=MonoTests.$(TESTNAME)
+else
 TESTNAME_ARG = -run=MonoTests.$(TESTNAME)
 endif
+endif
 
 ifdef ALWAYS_AOT
 test-local-aot-compile: $(topdir)/build/deps/nunit-$(PROFILE).stamp
index deb3458cc86fce5924c0eb75d3b084adb1322554..e32214de7dedde5e893a303a5a4e07da524c5219 100644 (file)
@@ -36,22 +36,28 @@ namespace Microsoft.Win32
 {
        public static class RegistryAclExtensions
        {
-               [MonoTODO]
                public static RegistrySecurity GetAccessControl (this RegistryKey key)
                {
-                       throw new NotImplementedException ();
+                       if (key == null)
+                               throw new ArgumentNullException (nameof (key));
+
+                       return key.GetAccessControl ();
                }
 
-               [MonoTODO]
                public static RegistrySecurity GetAccessControl (this RegistryKey key, AccessControlSections includeSections)
                {
-                       throw new NotImplementedException ();
+                       if (key == null)
+                               throw new ArgumentNullException (nameof (key));
+
+                       return key.GetAccessControl (includeSections);
                }
 
-               [MonoTODO]
                public static void SetAccessControl (this RegistryKey key, RegistrySecurity registrySecurity)
                {
-                       throw new NotImplementedException ();
+                       if (key == null)
+                               throw new ArgumentNullException (nameof (key));
+
+                       key.SetAccessControl (registrySecurity);
                }
        }
 }
\ No newline at end of file
index 7f6a474ab61d72bde71cbe01dadab76dc151849b..0b5d548674510c53b5d57fe865d507423ed923e6 100644 (file)
@@ -37,36 +37,54 @@ namespace System.Diagnostics
                [MonoTODO]
                public static IntPtr GetNativeImageBase (this StackFrame stackFrame)
                {
+                       if (stackFrame == null)
+                               throw new ArgumentNullException (nameof (stackFrame));
+
                        throw new NotImplementedException ();
                }
 
                [MonoTODO]
                public static IntPtr GetNativeIP (this StackFrame stackFrame)
                {
+                       if (stackFrame == null)
+                               throw new ArgumentNullException (nameof (stackFrame));
+
                        throw new NotImplementedException ();
                }
 
                [MonoTODO]
                public static bool HasNativeImage (this StackFrame stackFrame)
                {
+                       if (stackFrame == null)
+                               throw new ArgumentNullException (nameof (stackFrame));
+
                        throw new NotImplementedException ();
                }
 
                [MonoTODO]
                public static bool HasMethod (this StackFrame stackFrame)
                {
+                       if (stackFrame == null)
+                               throw new ArgumentNullException (nameof (stackFrame));
+
                        throw new NotImplementedException ();
                }
 
                [MonoTODO]
                public static bool HasILOffset (this StackFrame stackFrame)
                {
+                       if (stackFrame == null)
+                               throw new ArgumentNullException (nameof (stackFrame));
+
                        throw new NotImplementedException ();
                }
 
                [MonoTODO]
                public static bool HasSource (this StackFrame stackFrame)
                {
+                       if (stackFrame == null)
+                               throw new ArgumentNullException (nameof (stackFrame));
+
                        throw new NotImplementedException ();
                }
        }
index 7953b29b9ab9b6843d70fa311af8aa449abd872d..de606a86dcebf511195cdb1d61c5cf5d9af9efa0 100644 (file)
@@ -33,28 +33,36 @@ namespace System
 {
        public static class StringNormalizationExtensions
        {
-               [MonoTODO]
                public static bool IsNormalized(this string value)
                {
-                       throw new NotImplementedException ();
+                       if (value == null)
+                               throw new ArgumentNullException (nameof (value));
+
+                       return value.IsNormalized ();
                }
 
-               [MonoTODO]
                public static bool IsNormalized(this string value, NormalizationForm normalizationForm)
                {
-                       throw new NotImplementedException ();
+                       if (value == null)
+                               throw new ArgumentNullException (nameof (value));
+
+                       return value.IsNormalized (normalizationForm);
                }
 
-               [MonoTODO]
                public static String Normalize(this string value)
                {
-                       throw new NotImplementedException ();
+                       if (value == null)
+                               throw new ArgumentNullException (nameof (value));
+
+                       return value.Normalize ();
                }
 
-               [MonoTODO]
                public static String Normalize(this string value, NormalizationForm normalizationForm)
                {
-                       throw new NotImplementedException ();
+                       if (value == null)
+                               throw new ArgumentNullException (nameof (value));
+
+                       return value.Normalize (normalizationForm);
                }
        }
 }
index 1dd8d97ab5e13d56ec958fa2d3301980b365e90c..6baeefd5dd9da7f05871f65696b697e0aa5b1d9c 100644 (file)
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
+using System.Security.AccessControl;
+
 namespace System.IO
 {
-       public static partial class FileSystemAclExtensions
+       public static class FileSystemAclExtensions
        {
-               [MonoTODO]
-               public static System.Security.AccessControl.DirectorySecurity GetAccessControl(this System.IO.DirectoryInfo directoryInfo)
+               public static DirectorySecurity GetAccessControl(this DirectoryInfo directoryInfo)
                {
-                       throw new NotImplementedException ();
+                       if (directoryInfo == null)
+                               throw new ArgumentNullException (nameof (directoryInfo));
+
+                       return directoryInfo.GetAccessControl ();
                }
 
-               [MonoTODO]
-               public static System.Security.AccessControl.DirectorySecurity GetAccessControl(this System.IO.DirectoryInfo directoryInfo, System.Security.AccessControl.AccessControlSections includeSections)
+               public static DirectorySecurity GetAccessControl(this DirectoryInfo directoryInfo, AccessControlSections includeSections)
                {
-                       throw new NotImplementedException ();
+                       if (directoryInfo == null)
+                               throw new ArgumentNullException (nameof (directoryInfo));
+
+                       return directoryInfo.GetAccessControl (includeSections);
                }
 
-               [MonoTODO]
-               public static System.Security.AccessControl.FileSecurity GetAccessControl(this System.IO.FileInfo fileInfo)
+               public static FileSecurity GetAccessControl(this FileInfo fileInfo)
                {
-                       throw new NotImplementedException ();
+                       if (fileInfo == null)
+                               throw new ArgumentNullException (nameof (fileInfo));
+
+                       return fileInfo.GetAccessControl ();
                }
 
-               [MonoTODO]
-               public static System.Security.AccessControl.FileSecurity GetAccessControl(this System.IO.FileInfo fileInfo, System.Security.AccessControl.AccessControlSections includeSections)
+               public static FileSecurity GetAccessControl(this FileInfo fileInfo, AccessControlSections includeSections)
                {
-                       throw new NotImplementedException ();
+                       if (fileInfo == null)
+                               throw new ArgumentNullException (nameof (fileInfo));
+
+                       return fileInfo.GetAccessControl (includeSections);
                }
 
-               [MonoTODO]
-               public static System.Security.AccessControl.FileSecurity GetAccessControl(this System.IO.FileStream fileStream)
+               public static FileSecurity GetAccessControl(this FileStream fileStream)
                {
-                       throw new NotImplementedException ();
+                       if (fileStream == null)
+                               throw new ArgumentNullException (nameof (fileStream));
+
+                       return fileStream.GetAccessControl ();
                }
 
-               [MonoTODO]
-               public static void SetAccessControl(this System.IO.DirectoryInfo directoryInfo, System.Security.AccessControl.DirectorySecurity directorySecurity)
+               public static void SetAccessControl(this DirectoryInfo directoryInfo, DirectorySecurity directorySecurity)
                {
-                       throw new NotImplementedException ();
+                       if (directoryInfo == null)
+                               throw new ArgumentNullException (nameof (directoryInfo));
+
+                       directoryInfo.SetAccessControl (directorySecurity);
                }
 
-               [MonoTODO]
-               public static void SetAccessControl(this System.IO.FileInfo fileInfo, System.Security.AccessControl.FileSecurity fileSecurity)
+               public static void SetAccessControl(this FileInfo fileInfo, FileSecurity fileSecurity)
                {
-                       throw new NotImplementedException ();
+                       if (fileInfo == null)
+                               throw new ArgumentNullException (nameof (fileInfo));
+
+                       fileInfo.SetAccessControl (fileSecurity);
                }
 
-               [MonoTODO]
-               public static void SetAccessControl(this System.IO.FileStream fileStream, System.Security.AccessControl.FileSecurity fileSecurity)
+               public static void SetAccessControl(this FileStream fileStream, FileSecurity fileSecurity)
                {
-                       throw new NotImplementedException ();
+                       if (fileStream == null)
+                               throw new ArgumentNullException (nameof (fileStream));
+
+                       fileStream.SetAccessControl (fileSecurity);
                }
        }
 }
\ No newline at end of file
index a3e24ede013d8de80d1786bb558efecd7d8fab91..c0665fc07095af47bbc5f7c9de2f7093f5288ba2 100644 (file)
@@ -28,12 +28,12 @@ namespace System.Net.Sockets
                 state: socket);
         }
 
-        public static Task ConnectAsync(this Socket socket, EndPoint remoteEndPoint)
+        public static Task ConnectAsync(this Socket socket, EndPoint remoteEP)
         {
             return Task.Factory.FromAsync(
                 (targetEndPoint, callback, state) => ((Socket)state).BeginConnect(targetEndPoint, callback, state),
                 asyncResult => ((Socket)asyncResult.AsyncState).EndConnect(asyncResult),
-                remoteEndPoint,
+                remoteEP,
                 state: socket);
         }
 
@@ -229,7 +229,7 @@ namespace System.Net.Sockets
             this Socket socket,
             ArraySegment<byte> buffer,
             SocketFlags socketFlags,
-            EndPoint remoteEndPoint)
+            EndPoint remoteEP)
         {
             return Task<int>.Factory.FromAsync(
                 (targetBuffer, flags, endPoint, callback, state) => ((Socket)state).BeginSendTo(
@@ -243,7 +243,7 @@ namespace System.Net.Sockets
                 asyncResult => ((Socket)asyncResult.AsyncState).EndSendTo(asyncResult),
                 buffer,
                 socketFlags,
-                remoteEndPoint,
+                remoteEP,
                 state: socket);
         }
     }
diff --git a/mcs/class/Facades/System.Private.CoreLib.InteropServices/AssemblyInfo.cs b/mcs/class/Facades/System.Private.CoreLib.InteropServices/AssemblyInfo.cs
deleted file mode 100644 (file)
index 833904b..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// 
-// Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)
-// 
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-// 
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-// 
-
-using System;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-[assembly: AssemblyTitle ("System.Private.CoreLib.InteropServices.dll")]
-[assembly: AssemblyDescription ("System.Private.CoreLib.InteropServices.dll")]
-[assembly: AssemblyDefaultAlias ("System.Private.CoreLib.InteropServices.dll")]
-[assembly: AssemblyCompany ("Xamarin, Inc.")]
-[assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
-[assembly: AssemblyCopyright ("Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)")]
-[assembly: AssemblyVersion ("4.0.0.0")]
-[assembly: AssemblyInformationalVersion ("4.0.0.0")]
-[assembly: AssemblyFileVersion ("4.0.0.0")]
-[assembly: AssemblyDelaySign (true)]
-[assembly: AssemblyKeyFile ("../../msfinal.pub")]
diff --git a/mcs/class/Facades/System.Private.CoreLib.InteropServices/Facades_System.Private.CoreLib.InteropServices-net_4_x.csproj b/mcs/class/Facades/System.Private.CoreLib.InteropServices/Facades_System.Private.CoreLib.InteropServices-net_4_x.csproj
deleted file mode 100644 (file)
index c81a035..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>\r
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
-  <PropertyGroup>\r
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
-    <ProductVersion>9.0.30729</ProductVersion>\r
-    <SchemaVersion>2.0</SchemaVersion>\r
-    <ProjectGuid>{5D05F5E2-7378-4A35-B1A3-76ABEB4A71C3}</ProjectGuid>\r
-    <OutputType>Library</OutputType>\r
-    <NoWarn>1699,1616,1699</NoWarn>\r
-    <OutputPath>./../../../class/lib/net_4_x/Facades</OutputPath>\r
-    <IntermediateOutputPath>obj-Facades</IntermediateOutputPath>\r
-    <GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>\r
-    <NoStdLib>True</NoStdLib>\r
-    \r
-    <NoConfig>True</NoConfig>\r
-    \r
-    <AppDesignerFolder>Properties</AppDesignerFolder>\r
-    <RootNamespace>\r
-    </RootNamespace>\r
-    <AssemblyName>System.Private.CoreLib.InteropServices</AssemblyName>\r
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>\r
-    <FileAlignment>512</FileAlignment>\r
-  </PropertyGroup>\r
-    <PropertyGroup>\r
-    <SignAssembly>true</SignAssembly>\r
-    <DelaySign>true</DelaySign>\r
-  </PropertyGroup>\r
-  <PropertyGroup>\r
-    <AssemblyOriginatorKeyFile>../../msfinal.pub</AssemblyOriginatorKeyFile>\r
-  </PropertyGroup>\r
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
-    <DebugSymbols>true</DebugSymbols>\r
-    <DebugType>full</DebugType>\r
-    <NoWarn>1699,1616,1699</NoWarn>\r
-    <Optimize>false</Optimize>\r
-    <DefineConstants>TRACE;NET_4_0;NET_4_5;NET_4_6;MONO;DISABLE_CAS_USE</DefineConstants>\r
-    <ErrorReport>prompt</ErrorReport>\r
-    <WarningLevel>4</WarningLevel>\r
-  </PropertyGroup>\r
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
-    <DebugType>pdbonly</DebugType>\r
-    <NoWarn>1699,1616,1699</NoWarn>\r
-    <Optimize>true</Optimize>\r
-    <DefineConstants>NET_4_0;NET_4_5;NET_4_6;MONO;DISABLE_CAS_USE</DefineConstants>\r
-    <ErrorReport>prompt</ErrorReport>\r
-    <WarningLevel>4</WarningLevel>\r
-  </PropertyGroup>\r
-  <!-- Set AddAdditionalExplicitAssemblyReferences to false, otherwise if targetting .NET4.0, \r
-  Microsoft.NETFramework.props will force a dependency on the assembly System.Core. This\r
-  is a problem to compile the Mono mscorlib.dll -->\r
-  <PropertyGroup>\r
-    <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>\r
-  </PropertyGroup>\r
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />\r
-  <ItemGroup>\r
-    <Compile Include="AssemblyInfo.cs" />\r
-    <Compile Include="TypeForwarders.cs" />\r  </ItemGroup>\r
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r
-       Other similar extension points exist, see Microsoft.Common.targets.\r
-  <Target Name="BeforeBuild">\r
-  </Target>\r
-  <Target Name="AfterBuild">\r
-  </Target>\r
-  -->\r
-  <PropertyGroup>\r
-    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
-
-    </PreBuildEvent>\r
-    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">\r
-\r
-    </PreBuildEvent>\r
-    <PostBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
-
-    </PostBuildEvent>\r
-    <PostBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">\r
-\r
-    </PostBuildEvent>\r
-  </PropertyGroup>\r
-  <ItemGroup>\r
-    <ProjectReference Include="../../corlib/corlib-net_4_x.csproj">\r
-      <Project>{2CA6026B-2DC8-4C4C-A12C-1E8234049DB7}</Project>\r
-      <Name>corlib-net_4_x</Name>\r
-    </ProjectReference>\r
-    <ProjectReference Include="../../System/System-net_4_x.csproj">\r
-      <Project>{2762E921-91A8-4C87-91E9-BA628013F753}</Project>\r
-      <Name>System-net_4_x</Name>\r
-    </ProjectReference>\r
-  </ItemGroup>\r
-  <ItemGroup>\r
-    <Folder Include="Properties\" />\r
-  </ItemGroup>\r
-</Project>\r
-
diff --git a/mcs/class/Facades/System.Private.CoreLib.InteropServices/Makefile b/mcs/class/Facades/System.Private.CoreLib.InteropServices/Makefile
deleted file mode 100644 (file)
index 7b03ca8..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-MCS_BUILD_DIR = ../../../build
-
-thisdir = class/Facades/System.Private.CoreLib.InteropServices
-SUBDIRS = 
-include $(MCS_BUILD_DIR)/rules.make
-
-LIBRARY_SUBDIR = Facades
-LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)/Facades
-
-LIBRARY = System.Private.CoreLib.InteropServices.dll
-
-KEY_FILE = ../../msfinal.pub
-SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
-LIB_REFS = System
-LIB_MCS_FLAGS = $(SIGN_FLAGS) 
-
-PLATFORM_DEBUG_FLAGS =
-
-NO_TEST = yes
-
-include $(MCS_BUILD_DIR)/library.make
-
-
diff --git a/mcs/class/Facades/System.Private.CoreLib.InteropServices/System.Private.CoreLib.InteropServices-net_4_x.csproj b/mcs/class/Facades/System.Private.CoreLib.InteropServices/System.Private.CoreLib.InteropServices-net_4_x.csproj
deleted file mode 100644 (file)
index 4813330..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>\r
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
-  <PropertyGroup>\r
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
-    <ProductVersion>9.0.30729</ProductVersion>\r
-    <SchemaVersion>2.0</SchemaVersion>\r
-    <ProjectGuid>{BE4A05DF-5630-4E80-9521-7B4216229A60}</ProjectGuid>\r
-    <OutputType>Library</OutputType>\r
-    <NoWarn>1699,1616,1699</NoWarn>\r
-    <OutputPath>./../../../class/lib/net_4_x/Facades</OutputPath>\r
-    <NoStdLib>True</NoStdLib>\r
-    <NoConfig>True</NoConfig>\r
-    \r
-    <AppDesignerFolder>Properties</AppDesignerFolder>\r
-    <RootNamespace>\r
-    </RootNamespace>\r
-    <AssemblyName>System.Private.CoreLib.InteropServices</AssemblyName>\r
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>\r
-    <FileAlignment>512</FileAlignment>\r
-  </PropertyGroup>\r
-    <PropertyGroup>\r
-    <SignAssembly>true</SignAssembly>\r
-    <DelaySign>true</DelaySign>\r
-  </PropertyGroup>\r
-  <PropertyGroup>\r
-    <AssemblyOriginatorKeyFile>../../msfinal.pub</AssemblyOriginatorKeyFile>\r
-  </PropertyGroup>\r
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
-    <DebugSymbols>true</DebugSymbols>\r
-    <DebugType>full</DebugType>\r
-    <NoWarn>1699,1616,1699</NoWarn>\r
-    <Optimize>false</Optimize>\r
-    <DefineConstants>DEBUG;TRACE;NET_4_0;NET_4_5;NET_4_6;MONO;DISABLE_CAS_USE</DefineConstants>\r
-    <ErrorReport>prompt</ErrorReport>\r
-    <WarningLevel>4</WarningLevel>\r
-  </PropertyGroup>\r
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
-    <DebugType>pdbonly</DebugType>\r
-    <NoWarn>1699,1616,1699</NoWarn>\r
-    <Optimize>true</Optimize>\r
-    <DefineConstants>NET_4_0;NET_4_5;NET_4_6;MONO;DISABLE_CAS_USE</DefineConstants>\r
-    <ErrorReport>prompt</ErrorReport>\r
-    <WarningLevel>4</WarningLevel>\r
-  </PropertyGroup>\r
-  <!-- Set AddAdditionalExplicitAssemblyReferences to false, otherwise if targetting .NET4.0, \r
-  Microsoft.NETFramework.props will force a dependency on the assembly System.Core. This\r
-  is a problem to compile the Mono mscorlib.dll -->\r
-  <PropertyGroup>\r
-    <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>\r
-  </PropertyGroup>\r
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />\r
-  <ItemGroup>\r
-    <Compile Include="AssemblyInfo.cs" />\r
-    <Compile Include="TypeForwarders.cs" />\r  </ItemGroup>\r
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r
-       Other similar extension points exist, see Microsoft.Common.targets.\r
-  <Target Name="BeforeBuild">\r
-  </Target>\r
-  <Target Name="AfterBuild">\r
-  </Target>\r
-  -->\r
-  <PropertyGroup>\r
-    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">\r
-\r
-    </PreBuildEvent>\r
-    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">\r
-\r
-    </PreBuildEvent>\r
-\r
-    <PostBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">\r
-\r
-    </PostBuildEvent>\r
-    <PostBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">\r
-\r
-    </PostBuildEvent>\r
-  </PropertyGroup>\r
-  <ItemGroup>\r
-    <ProjectReference Include="../../corlib/corlib-net_4_x.csproj">\r
-      <Project>{2CA6026B-2DC8-4C4C-A12C-1E8234049DB7}</Project>\r
-      <Name>corlib-net_4_x</Name>\r
-    </ProjectReference>\r
-    <ProjectReference Include="../../corlib/corlib-net_4_x.csproj">\r
-      <Project>{2CA6026B-2DC8-4C4C-A12C-1E8234049DB7}</Project>\r
-      <Name>corlib-net_4_x</Name>\r
-    </ProjectReference>\r
-    <ProjectReference Include="../../System/System-net_4_x.csproj">\r
-      <Project>{2762E921-91A8-4C87-91E9-BA628013F753}</Project>\r
-      <Name>System-net_4_x</Name>\r
-    </ProjectReference>\r
-  </ItemGroup>\r
-  <ItemGroup>\r
-    <Folder Include="Properties\" />\r
-  </ItemGroup>\r
-</Project>\r
-
diff --git a/mcs/class/Facades/System.Private.CoreLib.InteropServices/System.Private.CoreLib.InteropServices.dll.sources b/mcs/class/Facades/System.Private.CoreLib.InteropServices/System.Private.CoreLib.InteropServices.dll.sources
deleted file mode 100644 (file)
index 8e33d4d..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-TypeForwarders.cs
-AssemblyInfo.cs
-
diff --git a/mcs/class/Facades/System.Private.CoreLib.InteropServices/TypeForwarders.cs b/mcs/class/Facades/System.Private.CoreLib.InteropServices/TypeForwarders.cs
deleted file mode 100644 (file)
index 7a1269d..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-// 
-// Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)
-// 
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-// 
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-// 
-
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.CallingConvention))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.DllImportAttribute))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.GCHandle))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.GCHandleType))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.SafeHandle))]
-
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Internal.Reflection.Execution.PayForPlayExperience.MissingMetadataExceptionCreator))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.CompilerServices.DependencyReductionTypeRemoved))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.CompilerServices.PreInitializedAttribute))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.InteropExtensions))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.NativeCallableAttributes))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.RuntimeImportAttribute))]
index d9427c8562df6487a46975c45099eedec21584ca..8b9f6f86f5e9d2c2b029e77d896c9f54396a0f10 100644 (file)
@@ -30,7 +30,7 @@ using System.Runtime.CompilerServices;
 [assembly: AssemblyCompany ("Xamarin, Inc.")]
 [assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
 [assembly: AssemblyCopyright ("Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)")]
-[assembly: AssemblyVersion ("4.0.0.0")]
+[assembly: AssemblyVersion ("4.0.1.0")]
 [assembly: AssemblyInformationalVersion ("4.0.0.0")]
 [assembly: AssemblyFileVersion ("4.0.0.0")]
 [assembly: AssemblyDelaySign (true)]
index 11f62613d08ffd5a2322a42016e8873a974d4740..cd48993eda733461a63b78affd8406309de47df9 100644 (file)
@@ -30,7 +30,7 @@ using System.Runtime.CompilerServices;
 [assembly: AssemblyCompany ("Xamarin, Inc.")]
 [assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
 [assembly: AssemblyCopyright ("Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)")]
-[assembly: AssemblyVersion ("4.0.0.0")]
+[assembly: AssemblyVersion ("4.0.1.0")]
 [assembly: AssemblyInformationalVersion ("4.0.0.0")]
 [assembly: AssemblyFileVersion ("4.0.0.0")]
 [assembly: AssemblyDelaySign (true)]
index 2acf0c84993cad35d47963bf436d471d0641ed3d..03e71faf4b5db5a0e72c47d9fbad04ad216a95b2 100644 (file)
@@ -30,7 +30,7 @@ using System.Runtime.CompilerServices;
 [assembly: AssemblyCompany ("Xamarin, Inc.")]
 [assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
 [assembly: AssemblyCopyright ("Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)")]
-[assembly: AssemblyVersion ("4.0.0.0")]
+[assembly: AssemblyVersion ("4.0.1.0")]
 [assembly: AssemblyInformationalVersion ("4.0.0.0")]
 [assembly: AssemblyFileVersion ("4.0.0.0")]
 [assembly: AssemblyDelaySign (true)]
index 661cd67a0eaf371b9a56c8d34e77f940d9cfd80f..2943d31dc0a5ad9cce109751cb8d53b9894b2e46 100644 (file)
@@ -15,199 +15,199 @@ namespace System.Reflection
 {
     public static class TypeExtensions
     {
-        public static ConstructorInfo GetConstructor(Type type, Type[] types)
+        public static ConstructorInfo GetConstructor(this Type type, Type[] types)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetConstructor(types);
         }
 
-        public static ConstructorInfo[] GetConstructors(Type type)
+        public static ConstructorInfo[] GetConstructors(this Type type)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetConstructors();
         }
 
-        public static ConstructorInfo[] GetConstructors(Type type, BindingFlags bindingAttr)
+        public static ConstructorInfo[] GetConstructors(this Type type, BindingFlags bindingAttr)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetConstructors(bindingAttr);
         }
 
-        public static MemberInfo[] GetDefaultMembers(Type type)
+        public static MemberInfo[] GetDefaultMembers(this Type type)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetDefaultMembers();
         }
 
-        public static EventInfo GetEvent(Type type, string name)
+        public static EventInfo GetEvent(this Type type, string name)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetEvent(name);
         }
 
-        public static EventInfo GetEvent(Type type, string name, BindingFlags bindingAttr)
+        public static EventInfo GetEvent(this Type type, string name, BindingFlags bindingAttr)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetEvent(name, bindingAttr);
         }
 
-        public static EventInfo[] GetEvents(Type type)
+        public static EventInfo[] GetEvents(this Type type)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetEvents();
         }
 
-        public static EventInfo[] GetEvents(Type type, BindingFlags bindingAttr)
+        public static EventInfo[] GetEvents(this Type type, BindingFlags bindingAttr)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetEvents(bindingAttr);
         }
 
-        public static FieldInfo GetField(Type type, string name)
+        public static FieldInfo GetField(this Type type, string name)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetField(name);
         }
 
-        public static FieldInfo GetField(Type type, string name, BindingFlags bindingAttr)
+        public static FieldInfo GetField(this Type type, string name, BindingFlags bindingAttr)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetField(name, bindingAttr);
         }
 
-        public static FieldInfo[] GetFields(Type type)
+        public static FieldInfo[] GetFields(this Type type)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetFields();
         }
 
-        public static FieldInfo[] GetFields(Type type, BindingFlags bindingAttr)
+        public static FieldInfo[] GetFields(this Type type, BindingFlags bindingAttr)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetFields(bindingAttr);
         }
 
-        public static Type[] GetGenericArguments(Type type)
+        public static Type[] GetGenericArguments(this Type type)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetGenericArguments();
         }
 
-        public static Type[] GetInterfaces(Type type)
+        public static Type[] GetInterfaces(this Type type)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetInterfaces();
         }
 
-        public static MemberInfo[] GetMember(Type type, string name)
+        public static MemberInfo[] GetMember(this Type type, string name)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetMember(name);
         }
 
-        public static MemberInfo[] GetMember(Type type, string name, BindingFlags bindingAttr)
+        public static MemberInfo[] GetMember(this Type type, string name, BindingFlags bindingAttr)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetMember(name, bindingAttr);
         }
 
-        public static MemberInfo[] GetMembers(Type type)
+        public static MemberInfo[] GetMembers(this Type type)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetMembers();
         }
 
-        public static MemberInfo[] GetMembers(Type type, BindingFlags bindingAttr)
+        public static MemberInfo[] GetMembers(this Type type, BindingFlags bindingAttr)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetMembers(bindingAttr);
         }
 
-        public static MethodInfo GetMethod(Type type, string name)
+        public static MethodInfo GetMethod(this Type type, string name)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetMethod(name);
         }
 
-        public static MethodInfo GetMethod(Type type, string name, BindingFlags bindingAttr)
+        public static MethodInfo GetMethod(this Type type, string name, BindingFlags bindingAttr)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetMethod(name, bindingAttr);
         }
 
-        public static MethodInfo GetMethod(Type type, string name, Type[] types)
+        public static MethodInfo GetMethod(this Type type, string name, Type[] types)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetMethod(name, types);
         }
 
-        public static MethodInfo[] GetMethods(Type type)
+        public static MethodInfo[] GetMethods(this Type type)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetMethods();
         }
 
-        public static MethodInfo[] GetMethods(Type type, BindingFlags bindingAttr)
+        public static MethodInfo[] GetMethods(this Type type, BindingFlags bindingAttr)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetMethods(bindingAttr);
         }
 
-        public static Type GetNestedType(Type type, string name, BindingFlags bindingAttr)
+        public static Type GetNestedType(this Type type, string name, BindingFlags bindingAttr)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetNestedType(name, bindingAttr);
         }
 
-        public static Type[] GetNestedTypes(Type type, BindingFlags bindingAttr)
+        public static Type[] GetNestedTypes(this Type type, BindingFlags bindingAttr)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetNestedTypes(bindingAttr);
         }
 
-        public static PropertyInfo[] GetProperties(Type type)
+        public static PropertyInfo[] GetProperties(this Type type)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetProperties();
         }
 
-        public static PropertyInfo[] GetProperties(Type type, BindingFlags bindingAttr)
+        public static PropertyInfo[] GetProperties(this Type type, BindingFlags bindingAttr)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetProperties(bindingAttr);
         }
 
-        public static PropertyInfo GetProperty(Type type, string name)
+        public static PropertyInfo GetProperty(this Type type, string name)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetProperty(name);
         }
 
-        public static PropertyInfo GetProperty(Type type, string name, BindingFlags bindingAttr)
+        public static PropertyInfo GetProperty(this Type type, string name, BindingFlags bindingAttr)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetProperty(name, bindingAttr);
         }
 
-        public static PropertyInfo GetProperty(Type type, string name, Type returnType)
+        public static PropertyInfo GetProperty(this Type type, string name, Type returnType)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetProperty(name, returnType);
         }
 
-        public static PropertyInfo GetProperty(Type type, string name, Type returnType, Type[] types)
+        public static PropertyInfo GetProperty(this Type type, string name, Type returnType, Type[] types)
         {
             Requires.NotNull(type, nameof(type));
             return type.GetProperty(name, returnType, types);
         }
 
-        public static bool IsAssignableFrom(Type type, Type c)
+        public static bool IsAssignableFrom(this Type type, Type c)
         {
             Requires.NotNull(type, nameof(type));
             return type.IsAssignableFrom(c);
         }
 
-        public static bool IsInstanceOfType(Type type, object o)
+        public static bool IsInstanceOfType(this Type type, object o)
         {
             Requires.NotNull(type, nameof(type));
             return type.IsInstanceOfType(o);
@@ -216,19 +216,19 @@ namespace System.Reflection
 
     public static class AssemblyExtensions
     {
-        public static Type[] GetExportedTypes(Assembly assembly)
+        public static Type[] GetExportedTypes(this Assembly assembly)
         {
             Requires.NotNull(assembly, nameof(assembly));
             return assembly.GetExportedTypes();
         }
 
-        public static Module[] GetModules(Assembly assembly)
+        public static Module[] GetModules(this Assembly assembly)
         {
             Requires.NotNull(assembly, nameof(assembly));
             return assembly.GetModules();
         }
 
-        public static Type[] GetTypes(Assembly assembly)
+        public static Type[] GetTypes(this Assembly assembly)
         {
             Requires.NotNull(assembly, nameof(assembly));
             return assembly.GetTypes();
@@ -237,37 +237,37 @@ namespace System.Reflection
 
     public static class EventInfoExtensions
     {
-        public static MethodInfo GetAddMethod(EventInfo eventInfo)
+        public static MethodInfo GetAddMethod(this EventInfo eventInfo)
         {
             Requires.NotNull(eventInfo, nameof(eventInfo));
             return eventInfo.GetAddMethod();
         }
 
-        public static MethodInfo GetAddMethod(EventInfo eventInfo, bool nonPublic)
+        public static MethodInfo GetAddMethod(this EventInfo eventInfo, bool nonPublic)
         {
             Requires.NotNull(eventInfo, nameof(eventInfo));
             return eventInfo.GetAddMethod(nonPublic);
         }
 
-        public static MethodInfo GetRaiseMethod(EventInfo eventInfo)
+        public static MethodInfo GetRaiseMethod(this EventInfo eventInfo)
         {
             Requires.NotNull(eventInfo, nameof(eventInfo));
             return eventInfo.GetRaiseMethod();
         }
 
-        public static MethodInfo GetRaiseMethod(EventInfo eventInfo, bool nonPublic)
+        public static MethodInfo GetRaiseMethod(this EventInfo eventInfo, bool nonPublic)
         {
             Requires.NotNull(eventInfo, nameof(eventInfo));
             return eventInfo.GetRaiseMethod(nonPublic);
         }
 
-        public static MethodInfo GetRemoveMethod(EventInfo eventInfo)
+        public static MethodInfo GetRemoveMethod(this EventInfo eventInfo)
         {
             Requires.NotNull(eventInfo, nameof(eventInfo));
             return eventInfo.GetRemoveMethod();
         }
 
-        public static MethodInfo GetRemoveMethod(EventInfo eventInfo, bool nonPublic)
+        public static MethodInfo GetRemoveMethod(this EventInfo eventInfo, bool nonPublic)
         {
             Requires.NotNull(eventInfo, nameof(eventInfo));
             return eventInfo.GetRemoveMethod(nonPublic);
@@ -337,7 +337,7 @@ namespace System.Reflection
 
     public static class MethodInfoExtensions
     {
-        public static MethodInfo GetBaseDefinition(MethodInfo method)
+        public static MethodInfo GetBaseDefinition(this MethodInfo method)
         {
             Requires.NotNull(method, nameof(method));
             return method.GetBaseDefinition();
@@ -361,37 +361,37 @@ namespace System.Reflection
 
     public static class PropertyInfoExtensions
     {
-        public static MethodInfo[] GetAccessors(PropertyInfo property)
+        public static MethodInfo[] GetAccessors(this PropertyInfo property)
         {
             Requires.NotNull(property, nameof(property));
             return property.GetAccessors();
         }
 
-        public static MethodInfo[] GetAccessors(PropertyInfo property, bool nonPublic)
+        public static MethodInfo[] GetAccessors(this PropertyInfo property, bool nonPublic)
         {
             Requires.NotNull(property, nameof(property));
             return property.GetAccessors(nonPublic);
         }
 
-        public static MethodInfo GetGetMethod(PropertyInfo property)
+        public static MethodInfo GetGetMethod(this PropertyInfo property)
         {
             Requires.NotNull(property, nameof(property));
             return property.GetGetMethod();
         }
 
-        public static MethodInfo GetGetMethod(PropertyInfo property, bool nonPublic)
+        public static MethodInfo GetGetMethod(this PropertyInfo property, bool nonPublic)
         {
             Requires.NotNull(property, nameof(property));
             return property.GetGetMethod(nonPublic);
         }
 
-        public static MethodInfo GetSetMethod(PropertyInfo property)
+        public static MethodInfo GetSetMethod(this PropertyInfo property)
         {
             Requires.NotNull(property, nameof(property));
             return property.GetSetMethod();
         }
 
-        public static MethodInfo GetSetMethod(PropertyInfo property, bool nonPublic)
+        public static MethodInfo GetSetMethod(this PropertyInfo property, bool nonPublic)
         {
             Requires.NotNull(property, nameof(property));
             return property.GetSetMethod(nonPublic);
index 94249720f6a1a2130d71d6bacff177e3bd5d47d0..361d3326ff581e40103016493acc53ccd59a4407 100644 (file)
 // THE SOFTWARE.
 // 
 
-#if !FULL_AOT_RUNTIME
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.ComImportAttribute))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.DispatchWrapper))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.ErrorWrapper))]
-#endif
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.DataMisalignedException))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.DllNotFoundException))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.Missing))]
index 59c85a4291e68e4d64bbfafa7b1c5d4a2b49de1c..8fb33b4f63ec675a571587103988e30d0cde7c80 100644 (file)
 // THE SOFTWARE.
 // 
 
+using System.Runtime.InteropServices;
+
 namespace System.Security
 {
        public static class SecureStringMarshal
        {
                public static IntPtr SecureStringToCoTaskMemAnsi (SecureString s)
                {
-                       throw new NotImplementedException ();
+                       return Marshal.SecureStringToCoTaskMemAnsi (s);
                }
 
                public static IntPtr SecureStringToCoTaskMemUnicode (SecureString s)
                {
-                       throw new NotImplementedException ();
+                       return Marshal.SecureStringToCoTaskMemUnicode (s);
                }
 
                public static IntPtr SecureStringToGlobalAllocAnsi (SecureString s)
                {
-                       throw new NotImplementedException ();
+                       return Marshal.SecureStringToGlobalAllocAnsi (s);
                }
 
                public static IntPtr SecureStringToGlobalAllocUnicode (SecureString s)
                {
-                       throw new NotImplementedException ();
+                       return Marshal.SecureStringToGlobalAllocUnicode (s);
                }
        }
 }
index f84a27d1c9a848f0cbb12a9d6a9a602b7c73c964..617465326fe16653be2dc1ff0ec4c6959c310dc1 100644 (file)
@@ -37,208 +37,180 @@ namespace System.ServiceProcess
 {
        public class ServiceController : IDisposable
        {
-               [MonoTODO]
                public bool CanPauseAndContinue
                {
                        get
                        {
-                               throw new NotImplementedException ();
+                               throw new PlatformNotSupportedException ();
                        }
                }
 
-               [MonoTODO]
                public bool CanShutdown
                {
                        get
                        {
-                               throw new NotImplementedException ();
+                               throw new PlatformNotSupportedException ();
                        }
                }
 
-               [MonoTODO]
                public bool CanStop
                {
                        get
                        {
-                               throw new NotImplementedException ();
+                               throw new PlatformNotSupportedException ();
                        }
                }
 
-               [MonoTODO]
                public ServiceController[] DependentServices
                {
                        get
                        {
-                               throw new NotImplementedException ();
+                               throw new PlatformNotSupportedException ();
                        }
                }
 
-               [MonoTODO]
                public string DisplayName
                {
                        get
                        {
-                               throw new NotImplementedException ();
+                               throw new PlatformNotSupportedException ();
                        }
                }
 
-               [MonoTODO]
                public string MachineName
                {
                        get
                        {
-                               throw new NotImplementedException ();
+                               throw new PlatformNotSupportedException ();
                        }
                }
 
-               [MonoTODO]
                public SafeHandle ServiceHandle
                {
                        get
                        {
-                               throw new NotImplementedException ();
+                               throw new PlatformNotSupportedException ();
                        }
                }
 
-               [MonoTODO]
                public string ServiceName
                {
                        get
                        {
-                               throw new NotImplementedException ();
+                               throw new PlatformNotSupportedException ();
                        }
                }
 
-               [MonoTODO]
                public ServiceController[] ServicesDependedOn
                {
                        get
                        {
-                               throw new NotImplementedException ();
+                               throw new PlatformNotSupportedException ();
                        }
                }
 
-               [MonoTODO]
                public ServiceType ServiceType
                {
                        get
                        {
-                               throw new NotImplementedException ();
+                               throw new PlatformNotSupportedException ();
                        }
                }
 
-               [MonoTODO]
                public ServiceStartMode StartType
                {
                        get
                        {
-                               throw new NotImplementedException ();
+                               throw new PlatformNotSupportedException ();
                        }
                }
 
-               [MonoTODO]
                public ServiceControllerStatus Status
                {
                        get
                        {
-                               throw new NotImplementedException ();
+                               throw new PlatformNotSupportedException ();
                        }
                }
 
-               [MonoTODO]
                public ServiceController (string name)
                {
-                       throw new NotImplementedException ();
+                       throw new PlatformNotSupportedException ();
                }
 
-               [MonoTODO]
                public ServiceController (string name, string machineName)
                {
-                       throw new NotImplementedException ();
+                       throw new PlatformNotSupportedException ();
                }
 
-               [MonoTODO]
                public void Continue ()
                {
-                       throw new NotImplementedException ();
+                       throw new PlatformNotSupportedException ();
                }
 
-               [MonoTODO]
                public void Dispose ()
                {
-                       throw new NotImplementedException ();
+                       throw new PlatformNotSupportedException ();
                }
 
-               [MonoTODO]
                protected virtual void Dispose (bool disposing)
                {
-                       throw new NotImplementedException ();
+                       throw new PlatformNotSupportedException ();
                }
 
-               [MonoTODO]
                public static ServiceController[] GetDevices ()
                {
-                       throw new NotImplementedException ();
+                       throw new PlatformNotSupportedException ();
                }
 
-               [MonoTODO]
                public static ServiceController[] GetDevices (string machineName)
                {
-                       throw new NotImplementedException ();
+                       throw new PlatformNotSupportedException ();
                }
 
-               [MonoTODO]
                public static ServiceController[] GetServices ()
                {
-                       throw new NotImplementedException ();
+                       throw new PlatformNotSupportedException ();
                }
 
-               [MonoTODO]
                public static ServiceController[] GetServices (string machineName)
                {
-                       throw new NotImplementedException ();
+                       throw new PlatformNotSupportedException ();
                }
 
-               [MonoTODO]
                public void Pause ()
                {
-                       throw new NotImplementedException ();
+                       throw new PlatformNotSupportedException ();
                }
 
-               [MonoTODO]
                public void Refresh ()
                {
-                       throw new NotImplementedException ();
+                       throw new PlatformNotSupportedException ();
                }
 
-               [MonoTODO]
                public void Start ()
                {
-                       throw new NotImplementedException ();
+                       throw new PlatformNotSupportedException ();
                }
 
-               [MonoTODO]
                public void Start (string[] args)
                {
-                       throw new NotImplementedException ();
+                       throw new PlatformNotSupportedException ();
                }
 
-               [MonoTODO]
                public void Stop ()
                {
-                       throw new NotImplementedException ();
+                       throw new PlatformNotSupportedException ();
                }
 
-               [MonoTODO]
                public void WaitForStatus (ServiceControllerStatus desiredStatus)
                {
-                       throw new NotImplementedException ();
+                       throw new PlatformNotSupportedException ();
                }
 
-               [MonoTODO]
                public void WaitForStatus (ServiceControllerStatus desiredStatus, TimeSpan timeout)
                {
-                       throw new NotImplementedException ();
+                       throw new PlatformNotSupportedException ();
                }
        }
 }
index c6448d899ffe5a7ee56d31b1a59929fde1b66a47..5dbf4041b386ca9a4fc955f73caa304632832f1f 100644 (file)
@@ -36,22 +36,19 @@ namespace System.ServiceProcess
 {
        public class TimeoutException : Exception
        {
-               [MonoTODO]
                public TimeoutException ()
                {
-                       throw new NotImplementedException ();
+                       throw new PlatformNotSupportedException ();
                }
 
-               [MonoTODO]
                public TimeoutException (string message)
                {
-                       throw new NotImplementedException ();
+                       throw new PlatformNotSupportedException ();
                }
 
-               [MonoTODO]
                public TimeoutException (string message, Exception innerException)
                {
-                       throw new NotImplementedException ();
+                       throw new PlatformNotSupportedException ();
                }
        }
 }
index af61a50a0e6c8c45389a5df1e60839a17b551ab5..99b03b28edf5ea1551c5b2d28fd22309f8d2bb07 100644 (file)
@@ -36,40 +36,52 @@ namespace System.Threading
 {
     public static class ThreadingAclExtensions
     {
-        [MonoTODO]
-        public static EventWaitHandleSecurity GetAccessControl (EventWaitHandle handle)
+        public static EventWaitHandleSecurity GetAccessControl (this EventWaitHandle handle)
         {
-            throw new NotImplementedException ();
+            if (handle == null)
+                throw new ArgumentNullException (nameof (handle));
+
+            return handle.GetAccessControl ();
         }
 
-        [MonoTODO]
-        public static void SetAccessControl (EventWaitHandle handle, EventWaitHandleSecurity eventSecurity)
+        public static void SetAccessControl (this EventWaitHandle handle, EventWaitHandleSecurity eventSecurity)
         {
-            throw new NotImplementedException ();
+            if (handle == null)
+                throw new ArgumentNullException (nameof (handle));
+
+            handle.SetAccessControl (eventSecurity);
         }
 
-        [MonoTODO]
-        public static MutexSecurity GetAccessControl (Mutex mutex)
+        public static MutexSecurity GetAccessControl (this Mutex mutex)
         {
-            throw new NotImplementedException ();
+            if (mutex == null)
+                throw new ArgumentNullException (nameof (mutex));
+
+            return mutex.GetAccessControl ();
         }
 
-        [MonoTODO]
-        public static void SetAccessControl (Mutex mutex, MutexSecurity mutexSecurity)
+        public static void SetAccessControl (this Mutex mutex, MutexSecurity mutexSecurity)
         {
-            throw new NotImplementedException ();
+            if (mutex == null)
+                throw new ArgumentNullException (nameof (mutex));
+
+            mutex.SetAccessControl (mutexSecurity);
         }
 
-        [MonoTODO]
-        public static SemaphoreSecurity GetAccessControl (Semaphore semaphore)
+        public static SemaphoreSecurity GetAccessControl (this Semaphore semaphore)
         {
-            throw new NotImplementedException ();
+            if (semaphore == null)
+                throw new ArgumentNullException (nameof (semaphore));
+
+            return semaphore.GetAccessControl ();
         }
 
-        [MonoTODO]
-        public static void SetAccessControl (Semaphore semaphore, SemaphoreSecurity semaphoreSecurity)
+        public static void SetAccessControl (this Semaphore semaphore, SemaphoreSecurity semaphoreSecurity)
         {
-            throw new NotImplementedException ();
+            if (semaphore == null)
+                throw new ArgumentNullException (nameof (semaphore));
+
+            semaphore.SetAccessControl (semaphoreSecurity);
         }
     }
 }
\ No newline at end of file
index df1dd020404535839b69b35be715b25cdb7a9275..c980d70840d4d7c2def8ece1b62f4ce110d13c8c 100644 (file)
@@ -24,7 +24,7 @@ System.Security.Cryptography.Encryption.Aes System.Security.Cryptography.Encrypt
 System.Security.Cryptography.Hashing.Algorithms System.Security.Cryptography.RSA System.Security.Cryptography.RandomNumberGenerator \
 System.Security.Principal.Windows System.Threading.Thread System.Threading.ThreadPool \
 System.Xml.XPath System.Xml.XmlDocument System.Xml.Xsl.Primitives Microsoft.Win32.Registry.AccessControl System.Diagnostics.StackTrace System.Globalization.Extensions \
-System.IO.FileSystem.AccessControl System.Private.CoreLib.InteropServices System.Reflection.TypeExtensions \
+System.IO.FileSystem.AccessControl System.Reflection.TypeExtensions \
 System.Security.SecureString System.Threading.AccessControl System.Threading.Overlapped System.Xml.XPath.XDocument \
 System.Security.Cryptography.Primitives System.Text.Encoding.CodePages System.IO.FileSystem.Watcher \
 System.Security.Cryptography.ProtectedData System.ServiceProcess.ServiceController System.IO.Pipes
index e864f4dfb3923773798acbc766d35e5c8c1376e5..2fbb9f18587853bd786d5125f7e73cd2a2a68e7f 100644 (file)
@@ -58,11 +58,9 @@ namespace MonoTests.Microsoft.Build.Construction
                                ProjectRootElement.Create (XmlReader.Create (new StringReader (" <root/>")));
                                Assert.Fail ("should throw InvalidProjectFileException");
                        } catch (InvalidProjectFileException ex) {
-                               #if NET_4_5
                                Assert.AreEqual (1, ex.LineNumber, "#1");
                                // it is very interesting, but unlike XmlReader.LinePosition it returns the position for '<'.
                                Assert.AreEqual (2, ex.ColumnNumber, "#2");
-                               #endif
                        }
                }
 
@@ -102,11 +100,9 @@ namespace MonoTests.Microsoft.Build.Construction
                                ProjectRootElement.Create (xml);
                                Assert.Fail ("should throw InvalidProjectFileException");
                        } catch (InvalidProjectFileException ex) {
-                               #if NET_4_5
                                Assert.AreEqual (1, ex.LineNumber, "#1");
                                // unlike unexpected element case which returned the position for '<', it does return the name start char...
                                Assert.AreEqual (70, ex.ColumnNumber, "#2");
-                               #endif
                        }
                }
 
index 970240fa74bda41ddb4db3b1b399e5d0e5c79211..700a41663d3b77777c48d5fc8408383a625bab50 100644 (file)
@@ -44,9 +44,7 @@ namespace MonoTests.Microsoft.Build.Evaluation
                {
                        var g = ProjectCollection.GlobalProjectCollection;
                        Assert.AreEqual (0, g.GlobalProperties.Count, "#1");
-                       #if NET_4_5
                        Assert.IsTrue (g.GlobalProperties.IsReadOnly, "#2");
-                       #endif
                }
                
                [Test]
index ac4e2d6610e7805edaebaaf6000e334b0f9b5c29..81392010d79782990e53bb98b5c5c385ff2a5479 100644 (file)
@@ -40,11 +40,9 @@ namespace MonoTests.Microsoft.Build.Evaluation
                        var ts = new Toolset ("4.3", "c:\\", ProjectCollection.GlobalProjectCollection, null);
                        Assert.IsNotNull (ts.Properties, "#1");
                        Assert.AreEqual (0, ts.Properties.Count, "#2");
-#if NET_4_5
                        Assert.IsNull (ts.DefaultSubToolsetVersion, "#3");
                        Assert.IsNotNull (ts.SubToolsets, "#4");
                        Assert.AreEqual (0, ts.SubToolsets.Count, "#5");
-#endif
                        Assert.AreEqual ("c:\\", ts.ToolsPath, "#6");
                        Assert.AreEqual ("4.3", ts.ToolsVersion, "#7");
                }
index ce13ce36469c04301533b099a8b023bbaff34683..5b24db55b27dc3247f7a1a9b5f726f1962efba82 100644 (file)
@@ -143,9 +143,7 @@ namespace MonoTests.Microsoft.Build.Execution
                        var root = ProjectRootElement.Create (xml);
                        root.FullPath = "ProjectInstanceTest.DependsOnTargets.proj";
                        var proj = new ProjectInstance (root);
-#if NET_4_5
                        Assert.AreEqual (2, proj.Targets.Count, "#1");
-#endif
                        Assert.IsFalse (proj.Build ("Bar", new ILogger [0]), "#2");
                }
                
index c94bef7d695da5454c2c73592fe838d51f7ebd0d..1663f71c682d768de1712ba13fa76f77e32c47d3 100644 (file)
@@ -42,7 +42,6 @@ namespace MonoTests.Microsoft.Build.Execution
        [TestFixture]
        public class ProjectTaskInstanceTest
        {
-#if NET_4_5
                [Test]
                public void OutputPropertyExists ()
                {
@@ -78,7 +77,6 @@ namespace MonoTests.Microsoft.Build.Execution
                        Assert.AreEqual (string.Empty, foo.Outputs, "#6");
                        Assert.AreEqual ("True", proj.GetPropertyValue ("C"), "#7");
                }
-#endif
        }
 }
 
index 6f757238cd4139809efe4ca4230369ff3344c0bc..34556edb930a21476dd4240285fe9865ea428db6 100644 (file)
@@ -125,9 +125,9 @@ namespace Mono.Data.Sqlite
        // Compatibility with versions < 3.5.0\r
         int n;\r
 \r
-       try {\r
+       if (UnsafeNativeMethods.use_sqlite3_open_v2) {\r
                n = UnsafeNativeMethods.sqlite3_open_v2(ToUTF8(strFilename), out db, (int)flags, IntPtr.Zero);\r
-       } catch (EntryPointNotFoundException) {\r
+       } else {\r
                Console.WriteLine ("Your sqlite3 version is old - please upgrade to at least v3.5.0!");\r
                n = UnsafeNativeMethods.sqlite3_open (ToUTF8 (strFilename), out db);\r
        }\r
index df8a5d787ab0daefe2ea5714dc621b1342f9f8b2..eca1bddfc6b406b6159fccd06ae84ca69a2f6486 100644 (file)
@@ -208,9 +208,9 @@ namespace Mono.Data.Sqlite
 #else\r
         ResetConnection(db);\r
         int n;\r
-        try {\r
+        if (UnsafeNativeMethods.use_sqlite3_close_v2) {\r
           n = UnsafeNativeMethods.sqlite3_close_v2(db);\r
-        } catch (EntryPointNotFoundException) {\r
+        } else {\r
           n = UnsafeNativeMethods.sqlite3_close(db);\r
         }\r
 #endif\r
index ba16a1763ff92b3141d7515bf8f463affd6c2ab4..bc9826d29f47dc83a2ad0875d14c046ae60b7343 100644 (file)
@@ -16,6 +16,27 @@ namespace Mono.Data.Sqlite
 #endif\r
   internal static class UnsafeNativeMethods\r
   {\r
+    internal static readonly bool use_sqlite3_close_v2 = false;\r
+    internal static readonly bool use_sqlite3_open_v2 = false;\r
+    internal static readonly bool use_sqlite3_create_function_v2 = false;\r
+    static UnsafeNativeMethods()\r
+    {\r
+      // calculate the version number parts\r
+      // https://www.sqlite.org/c3ref/c_source_id.html\r
+      // (<major> * 1000000) + (<minor> * 1000) + (<release>)\r
+      int versionNumber = sqlite3_libversion_number();\r
+      int release = versionNumber % 1000;\r
+      int minor = (versionNumber / 1000) % 1000;\r
+      int major = versionNumber / 1000000;\r
+      Version version = new Version(major, minor, release);\r
+\r
+      // set the various versions\r
+      // https://sqlite.org/changes.html\r
+      use_sqlite3_open_v2 = version >= new Version(3, 5, 0);\r
+      use_sqlite3_close_v2 = version >= new Version(3, 7, 14);\r
+      use_sqlite3_create_function_v2 = version >= new Version(3, 7, 3);\r
+    }\r
+\r
 #if !SQLITE_STANDARD\r
 \r
 #if !USE_INTEROP_DLL\r
@@ -730,6 +751,13 @@ namespace Mono.Data.Sqlite
 #endif\r
     internal static extern int sqlite3_free (IntPtr ptr);\r
 \r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_libversion_number();\r
+\r
     #endregion\r
   }\r
 \r
index 6617c146f6e138bb2e93ff51df41e1db164d1d84..cc2ab66960fa5f3ed36e6e70c52278f6a27d6fac 100644 (file)
@@ -829,9 +829,7 @@ public class Tests : TestsBase, ITest2
        }
 
        [MethodImplAttribute (MethodImplOptions.NoInlining)]
-#if NET_4_5
        [StateMachine (typeof (int))]
-#endif
        public static void locals2<T> (string[] args, int arg, T t, ref string rs, ref AStruct astruct) {
                long i = 42;
                string s = "AB";
@@ -1184,12 +1182,10 @@ public class Tests : TestsBase, ITest2
 
        [MethodImplAttribute (MethodImplOptions.NoInlining)]
        public static void unhandled_exception_user () {
-#if NET_4_5
                System.Threading.Tasks.Task.Factory.StartNew (() => {
                                Throw ();
                        });
                Thread.Sleep (10000);
-#endif
        }
 
        [MethodImplAttribute (MethodImplOptions.NoInlining)]
index 88ed411da35bcabcf36968da7de70dcaa9fc7d16..018435051777ac312d0831c2d71682ef37c6bee6 100644 (file)
@@ -2447,7 +2447,6 @@ public class DebuggerTests
                        Assert.AreEqual ("Exception", ex.Exception.Type.Name);
                }
 
-#if NET_4_5
                // out argument
                m = t.GetMethod ("invoke_out");
                var out_task = this_obj.InvokeMethodAsyncWithResult (e.Thread, m, new Value [] { vm.CreateValue (1), vm.CreateValue (null) }, InvokeOptions.ReturnOutArgs);
@@ -2460,7 +2459,6 @@ public class DebuggerTests
                out_task = this_obj.InvokeMethodAsyncWithResult (e.Thread, m, new Value [] { vm.CreateValue (1), vm.CreateValue (null) });
                out_args = out_task.Result.OutArgs;
                Assert.IsNull (out_args);
-#endif
 
                // newobj
                m = t.GetMethod (".ctor");
@@ -2484,7 +2482,6 @@ public class DebuggerTests
                v = t.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") }, InvokeOptions.Virtual);
                AssertValue ("ABC", v);
 
-#if NET_4_5
                // instance
                m = t.GetMethod ("invoke_pass_ref");
                var task = this_obj.InvokeMethodAsync (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
@@ -2494,7 +2491,6 @@ public class DebuggerTests
                m = t.GetMethod ("invoke_static_pass_ref");
                task = t.InvokeMethodAsync (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
                AssertValue ("ABC", task.Result);
-#endif
 
                // Argument checking
                
@@ -2588,7 +2584,6 @@ public class DebuggerTests
                v = t.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
                AssertValue (1, (v as StructMirror)["i"]);
 
-#if NET_4_5
                // Invoke a method which changes state
                s = frame.GetArgument (1) as StructMirror;
                t = s.Type;
@@ -2615,7 +2610,6 @@ public class DebuggerTests
                m = vm.RootDomain.Corlib.GetType ("System.Object").GetMethod ("ToString");
                v = s.InvokeMethod (e.Thread, m, null, InvokeOptions.Virtual);
                AssertValue ("42", v);
-#endif
        }
 
        [Test]
@@ -3790,7 +3784,6 @@ public class DebuggerTests
                vm = null;
        }
 
-#if NET_4_5
        [Test]
        public void UnhandledExceptionUserCode () {
                vm.Detach ();
@@ -3811,7 +3804,6 @@ public class DebuggerTests
                vm.Exit (0);
                vm = null;
        }
-#endif
 
        [Test]
        public void GCWhileSuspended () {
index dc95296fbed551d7da20859dbab91e5f821b4ca7..d98c051699e6d8e3e16a4896ac4d6e8f1f834242 100644 (file)
@@ -36,7 +36,6 @@ using MonoTests.Common;
 
 namespace MonoTests.System.ComponentModel.DataAnnotations
 {
-#if NET_4_5
        [TestFixture]
        public class CompareAttributeTest
        {
@@ -66,5 +65,4 @@ namespace MonoTests.System.ComponentModel.DataAnnotations
                        Assert.IsNotNull (sla.GetValidationResult (DateTime.Now, ctx), "#B-4");
                }
        }
-#endif
 }
index 846ee326176cf4aaa46dd69ba1421be78055a3af..00cc74573f4a174f276b9c3882654a8e829926fc 100644 (file)
@@ -36,7 +36,6 @@ using MonoTests.Common;
 
 namespace MonoTests.System.ComponentModel.DataAnnotations
 {
-#if NET_4_5
        [TestFixture]
        public class CreditCardAttributeTest
        {
@@ -56,5 +55,4 @@ namespace MonoTests.System.ComponentModel.DataAnnotations
                        Assert.IsFalse (sla.IsValid (DateTime.Now), "#A1-8");
                }
        }
-#endif
 }
index 552e3eae6a44da5ba82b9dfc5e24f6604f6a0b9b..f85887cef65a51e78d8769ed6f5d130342301dab 100644 (file)
@@ -36,7 +36,6 @@ using MonoTests.Common;
 
 namespace MonoTests.System.ComponentModel.DataAnnotations
 {
-#if NET_4_5
        [TestFixture]
        public class EmailAddressAttributeTest
        {
@@ -84,5 +83,4 @@ namespace MonoTests.System.ComponentModel.DataAnnotations
                                Assert.IsFalse (sla.IsValid (InvalidAddresses[i]), "#B1-{0}", i);
                }
        }
-#endif
 }
index 257161fc06c0998d4ed161a1a55c587d85337c47..6ef0263365ce154383e65d1aef9a42887ae5b032 100644 (file)
@@ -36,7 +36,6 @@ using MonoTests.Common;
 
 namespace MonoTests.System.ComponentModel.DataAnnotations
 {
-#if NET_4_5
        [TestFixture]
        public class FileExtensionsAttributeTest
        {
@@ -57,5 +56,4 @@ namespace MonoTests.System.ComponentModel.DataAnnotations
                        Assert.IsFalse (sla.IsValid (DateTime.Now), "#A1-8");
                }
        }
-#endif
 }
index 3ca6e0bf3d42c2c5bc022c8848f877aae9cc191a..ef9c95dfb755847dbda80726394c0488fc663563 100644 (file)
@@ -36,7 +36,6 @@ using MonoTests.Common;
 
 namespace MonoTests.System.ComponentModel.DataAnnotations
 {
-#if NET_4_5
        [TestFixture]
        public class PhoneAttributeTest
        {
@@ -54,5 +53,4 @@ namespace MonoTests.System.ComponentModel.DataAnnotations
                        Assert.IsFalse (sla.IsValid (DateTime.Now), "#A1-7");
                }
        }
-#endif
 }
index f6a3f9b546078bc94ddbe43598ca8cdb33f58b3e..6e36c961e353774dd0f024fb71287f0911d7f8aa 100644 (file)
@@ -21,10 +21,15 @@ System.IO.Pipes/AnonymousPipeClientStream.cs
 System.IO.Pipes/AnonymousPipeServerStream.cs
 System.IO.Pipes/NamedPipeClientStream.cs
 System.IO.Pipes/NamedPipeServerStream.cs
+System.IO.Pipes/PipeAccessRights.cs
+System.IO.Pipes/PipeAccessRule.cs
+System.IO.Pipes/PipeAuditRule.cs
 System.IO.Pipes/PipeDirection.cs
 System.IO.Pipes/PipeInterfaces.cs
 System.IO.Pipes/PipeOptions.cs
+System.IO.Pipes/PipeSecurity.cs
 System.IO.Pipes/PipeStream.cs
+System.IO.Pipes/PipeStreamImpersonationWorker.cs
 System.IO.Pipes/PipeTransmissionMode.cs
 
 ReferenceSources/SR.cs
index f367efd60c7562e4d1253707eed5828ace4a90e5..72d78659215f4a1661166b8791c9a345beb43182 100644 (file)
@@ -1,11 +1,6 @@
 #include common_System.Core.dll.sources
 #include dynamic_System.Core.dll.sources
 
-System.IO.Pipes/PipeAccessRights.cs
-System.IO.Pipes/PipeAccessRule.cs
-System.IO.Pipes/PipeAuditRule.cs
-System.IO.Pipes/PipeSecurity.cs
-System.IO.Pipes/PipeStreamImpersonationWorker.cs
 System.IO.Pipes/PipeUnix.cs
 System.IO.Pipes/PipeWin32.cs
 
index 4877d434a20c62afb5eb11c4277b62ee74d70ea5..9cb4b8a6eeae73078ce759004903398213075241 100644 (file)
@@ -38,6 +38,8 @@ using Mono.Data.Tds.Protocol;
 using System;
 using System.IO;
 using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
 using System.Collections;
 using System.ComponentModel;
 using System.Data;
@@ -1426,6 +1428,25 @@ namespace System.Data.SqlClient
                        throw new NotImplementedException ();   
                }
 
+               override public Task<T> GetFieldValueAsync<T> (int i, CancellationToken cancellationToken)
+               {
+                       return base.GetFieldValueAsync<T> (i, cancellationToken);
+               }
+
+               override public Stream GetStream (int i)
+               {
+                       return base.GetStream (i);
+               }
+               override public TextReader GetTextReader (int i)
+               {
+                       return base.GetTextReader (i);
+               }
+
+               override public Task<bool> IsDBNullAsync (int i, CancellationToken cancellationToken)
+               {
+                       return base.IsDBNullAsync (i, cancellationToken);
+               }
+
                #endregion // Methods
        }
 }
index 20d5c1ab0bf41c9e87f2eb16d793df4693eb67fe..ff7ebcbe0c4358ba1fd7e16beaf28bb15975c929 100644 (file)
@@ -61,7 +61,6 @@ namespace MonoTests.System.Data.Common
                {
                }
 
-               #if NET_4_5
                [Test]
                public void GetFieldValueTest ()
                {
@@ -155,7 +154,6 @@ namespace MonoTests.System.Data.Common
                        Assert.IsFalse (dataReader.Read (), "#5");
                }
 
-               #endif //NET_4_5
        }
 }
 
index 1d5090748cd12476a0c682e30a969bbb1c69611a..d55b6a06923f1f595cefa32666c6244339da49aa 100644 (file)
@@ -2,7 +2,6 @@
 // BootstrapContextTest.cs - NUnit Test Cases for System.IdentityModel.Tokens.BootstrapContext
 //
 
-#if NET_4_5
 using System;
 using System.IO;
 using System.IdentityModel.Tokens;
@@ -248,4 +247,3 @@ namespace MonoTests.System.IdentityModel.Tokens.net_4_5 {
                }
        }
 }
-#endif
index 21e80b5733e436012cda6b5477f9ef220c5c93c0..1a408f27117fac1a5cbac388c0d2d7cbd09aa258 100644 (file)
@@ -46,7 +46,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyCompany (Consts.MonoCompany)]
 [assembly: AssemblyProduct (Consts.MonoProduct)]
 [assembly: AssemblyCopyright (Consts.MonoCopyright)]
-[assembly: AssemblyVersion (Consts.FxVersion)]
+[assembly: AssemblyVersion ("4.0.0.0")]
 [assembly: SatelliteContractVersion (Consts.FxVersion)]
 [assembly: AssemblyInformationalVersion (Consts.FxFileVersion)]
 [assembly: AssemblyFileVersion (Consts.FxFileVersion)]
index d836c1e4ff2b75442e9e59883be7e127f316a278..27c57d109251c83dbfc42e9ebf1ebba3a5328216 100644 (file)
@@ -45,15 +45,15 @@ namespace System.Security.Cryptography.Pkcs {
                        _params = new byte [0];
                }
 
-               public AlgorithmIdentifier (Oid algorithm)
+               public AlgorithmIdentifier (Oid oid)
                {
-                       _oid = algorithm;
+                       _oid = oid;
                        _params = new byte [0];
                }
 
-               public AlgorithmIdentifier (Oid algorithm, int keyLength)
+               public AlgorithmIdentifier (Oid oid, int keyLength)
                {
-                       _oid = algorithm;
+                       _oid = oid;
                        _length = keyLength;
                        _params = new byte [0];
                }
index 32b675abb28ac40a7af30d039ecab9d79120aeca..3bf9efb989dc9bb946960b5bd771dfc3f3b33f23 100644 (file)
@@ -53,14 +53,14 @@ namespace System.Security.Cryptography.Pkcs {
                {
                } 
 
-               public ContentInfo (Oid oid, byte[] content) 
+               public ContentInfo (Oid contentType, byte[] content) 
                {
-                       if (oid == null)
-                               throw new ArgumentNullException ("oid");
+                       if (contentType == null)
+                               throw new ArgumentNullException ("contentType");
                        if (content == null)
                                throw new ArgumentNullException ("content");
 
-                       _oid = oid;
+                       _oid = contentType;
                        _content = content;
                }
 
index 1f57f5c55169931680496f4ed99ac4b1fd1e2aa6..3942e5bba1bb2f4a49e07374b3a01c6766360c62 100644 (file)
@@ -61,12 +61,12 @@ namespace System.Security.Cryptography.Pkcs {
                        _uattribs = new CryptographicAttributeObjectCollection ();
                }
 
-               public EnvelopedCms (ContentInfo content) : this ()
+               public EnvelopedCms (ContentInfo contentInfo) : this ()
                {
-                       if (content == null)
-                               throw new ArgumentNullException ("content");
+                       if (contentInfo == null)
+                               throw new ArgumentNullException ("contentInfo");
 
-                       _content = content;
+                       _content = contentInfo;
                }
 
                public EnvelopedCms (ContentInfo contentInfo, AlgorithmIdentifier encryptionAlgorithm)
index 4372574e1ee682c41f15f46b2d90d94aa816086d..1e07c4830d9bab68512ff729edc9e9647e048656 100644 (file)
@@ -45,9 +45,9 @@ namespace System.ServiceModel.Channels
                        return new DefaultAddressHeader (value);
                }
 
-               public static AddressHeader CreateAddressHeader (object value, XmlObjectSerializer formatter)
+               public static AddressHeader CreateAddressHeader (object value, XmlObjectSerializer serializer)
                {
-                       return new DefaultAddressHeader (value, formatter);
+                       return new DefaultAddressHeader (value, serializer);
                }
 
                public static AddressHeader CreateAddressHeader (string name, string ns, object value)
@@ -56,11 +56,11 @@ namespace System.ServiceModel.Channels
                }
 
                public static AddressHeader CreateAddressHeader (string name, string ns, object value, 
-                                                                XmlObjectSerializer formatter)
+                                                                XmlObjectSerializer serializer)
                {
-                       if (formatter == null)
-                               throw new ArgumentNullException ("formatter");
-                       return new DefaultAddressHeader (name, ns, value, formatter);
+                       if (serializer == null)
+                               throw new ArgumentNullException ("serializer");
+                       return new DefaultAddressHeader (name, ns, value, serializer);
                }
 
                public override bool Equals (object obj)
@@ -93,9 +93,9 @@ namespace System.ServiceModel.Channels
                        return GetValue<T> (new DataContractSerializer (typeof (T)));
                }
 
-               public T GetValue<T> (XmlObjectSerializer formatter)
+               public T GetValue<T> (XmlObjectSerializer serializer)
                {
-                       return (T) formatter.ReadObject (GetAddressHeaderReader ());
+                       return (T) serializer.ReadObject (GetAddressHeaderReader ());
                }
 
                protected abstract void OnWriteAddressHeaderContents (XmlDictionaryWriter writer);
index 3969ad3b5718affc8e44b05ed9633bc680d4199b..e8f2470d560aac4091cbfd6ad4840eb2a8f5a338 100644 (file)
@@ -47,8 +47,8 @@ namespace System.ServiceModel.Channels
                {
                }
 
-               public AddressHeaderCollection (IEnumerable<AddressHeader> headers)
-                       : base (GetList (headers))
+               public AddressHeaderCollection (IEnumerable<AddressHeader> addressHeaders)
+                       : base (GetList (addressHeaders))
                {
                }
 
index 06e682748d36104e694baf03bf8a44aa6604e1d5..2fecf2264681fbf522acf63c01b639ce6c9e81cb 100644 (file)
@@ -44,17 +44,17 @@ namespace System.ServiceModel.Channels
                BindingElementCollection elements; // for internal use
 
                public BindingContext (CustomBinding binding,
-                       BindingParameterCollection parms)
+                       BindingParameterCollection parameters)
                {
                        if (binding == null)
                                throw new ArgumentNullException ("binding");
-                       if (parms == null)
-                               throw new ArgumentNullException ("parms");
+                       if (parameters == null)
+                               throw new ArgumentNullException ("parameters");
 
                        this.binding = binding;
-                       parameters = new BindingParameterCollection ();
-                       foreach (var item in parms)
-                               parameters.Add (item);
+                       this.parameters = new BindingParameterCollection ();
+                       foreach (var item in parameters)
+                               this.parameters.Add (item);
                        this.elements = new BindingElementCollection ();
                        foreach (var item in binding.Elements)
                                this.elements.Add (item);
index a41eb6ed6deda42ab106de8c342b7cfb121d31df..be628e07ccb4bab99490552553ad709a2ccb3ad0 100644 (file)
@@ -40,7 +40,7 @@ namespace System.ServiceModel.Channels
                }
 
                [MonoTODO]
-               protected BindingElement (BindingElement other)
+               protected BindingElement (BindingElement elementToBeCloned)
                {
                }
 
index 762cb61b517513fc5a2cb5d42280a6367dc818a7..ea1fa491efa307fe767b38dc8dc94863bfea73ed 100644 (file)
@@ -38,14 +38,14 @@ namespace System.ServiceModel.Channels
                {
                }
 
-               public BindingElementCollection (BindingElement [] bindings)
+               public BindingElementCollection (BindingElement [] elements)
                {
-                       AddRange (bindings);
+                       AddRange (elements);
                }
 
-               public BindingElementCollection (IEnumerable<BindingElement> bindings)
+               public BindingElementCollection (IEnumerable<BindingElement> elements)
                {
-                       foreach (BindingElement e in bindings)
+                       foreach (BindingElement e in elements)
                                Add (e);
                }
 
index 693799434b3a819f530b61b1abb0beea42d04419..b251375659c2ba4eeab423badc432a29b093a2e1 100644 (file)
@@ -39,9 +39,9 @@ namespace System.ServiceModel.Channels
        {
                ChannelManagerBase manager;
 
-               protected ChannelBase (ChannelManagerBase manager)
+               protected ChannelBase (ChannelManagerBase channelManager)
                {
-                       this.manager = manager;
+                       this.manager = channelManager;
                }
 
                protected internal override TimeSpan DefaultCloseTimeout {
index cd573744e202d5b912c2f2e0d38c51751ae02738..d4df2f0f12fbe00c94cc284c68bbbf2a7299b997 100644 (file)
@@ -98,29 +98,29 @@ namespace System.ServiceModel.Channels
                }
 
                public TChannel CreateChannel (
-                       EndpointAddress remoteAddress)
+                       EndpointAddress address)
                {
-                       if (remoteAddress == null)
-                               throw new ArgumentNullException ("remoteAddress");
-                       return CreateChannel (remoteAddress, remoteAddress.Uri);
+                       if (address == null)
+                               throw new ArgumentNullException ("address");
+                       return CreateChannel (address, address.Uri);
                }
 
                public TChannel CreateChannel (
-                       EndpointAddress remoteAddress, Uri via)
+                       EndpointAddress address, Uri via)
                {
-                       if (remoteAddress == null)
-                               throw new ArgumentNullException ("remoteAddress");
+                       if (address == null)
+                               throw new ArgumentNullException ("address");
                        if (via == null)
                                throw new ArgumentNullException ("via");
 
                        ValidateCreateChannel ();
-                       var ch = OnCreateChannel (remoteAddress, via);
+                       var ch = OnCreateChannel (address, via);
                        channels.Add (ch);
                        return ch;
                }
 
                protected abstract TChannel OnCreateChannel (
-                       EndpointAddress remoteAddress, Uri via);
+                       EndpointAddress address, Uri via);
 
                protected override void OnAbort ()
                {
index cecbb8ccb120f20d974ebc7ef45dd543a33b4915..feb1f9ae7758247e9ce9563dccc7d1c09d4d0e25 100644 (file)
@@ -68,19 +68,19 @@ namespace System.ServiceModel.Channels
                        security = binding as ISecurityCapabilities;
                }
 
-               public CustomBinding (params BindingElement [] binding)
-                       : this ("CustomBinding", default_ns, binding)
+               public CustomBinding (params BindingElement [] bindingElementsInTopDownChannelStackOrder)
+                       : this ("CustomBinding", default_ns, bindingElementsInTopDownChannelStackOrder)
                {
                }
 
-               public CustomBinding (IEnumerable<BindingElement> bindingElements)
-                       : this (bindingElements, "CustomBinding", default_ns)
+               public CustomBinding (IEnumerable<BindingElement> bindingElementsInTopDownChannelStackOrder)
+                       : this (bindingElementsInTopDownChannelStackOrder, "CustomBinding", default_ns)
                {
                }
 
                public CustomBinding (string name, string ns,
-                       params BindingElement [] binding)
-                       : this (binding, name, ns)
+                       params BindingElement [] bindingElementsInTopDownChannelStackOrder)
+                       : this (bindingElementsInTopDownChannelStackOrder, name, ns)
                {
                }
 
index 37217165ecf94daf58a4a61d0330987cc36828a7..a2918a06e6dcb4e573c28addc3a4453b311dc60b 100644 (file)
@@ -47,20 +47,20 @@ namespace System.ServiceModel.Channels
 
                [MonoTODO]
                protected abstract bool OnTryCreateException (
-                       Message message, MessageFault fault, out Exception error);
+                       Message message, MessageFault fault, out Exception exception);
 
                [MonoTODO]
                protected abstract bool OnTryCreateFaultMessage (
-                       Exception error, out Message message);
+                       Exception exception, out Message message);
 
-               public bool TryCreateException (Message message, MessageFault fault, out Exception error)
+               public bool TryCreateException (Message message, MessageFault fault, out Exception exception)
                {
-                       return OnTryCreateException (message, fault, out error);
+                       return OnTryCreateException (message, fault, out exception);
                }
 
-               public bool TryCreateFaultMessage (Exception error, out Message message)
+               public bool TryCreateFaultMessage (Exception exception, out Message message)
                {
-                       return OnTryCreateFaultMessage (error, out message);
+                       return OnTryCreateFaultMessage (exception, out message);
                }
        }
 
index 77995b55137a7127af793c38a406ebe1bb7fe3d3..4e4d73f9fb186fe974c15de0cfd45fdfa692f4eb 100644 (file)
@@ -126,6 +126,7 @@ namespace System.ServiceModel.Channels
                        }
 
                        web_request.Timeout = (int) timeout.TotalMilliseconds;
+                       web_request.KeepAlive = httpbe.KeepAliveEnabled;
 
                        // There is no SOAP Action/To header when AddressingVersion is None.
                        if (message.Version.Envelope.Equals (EnvelopeVersion.Soap11) ||
index 191a182dfc70d4903f68d234834e0e11a25e09bc..d3c70970adfcd8490014b5cdfea51b888c8adfd7 100644 (file)
@@ -67,28 +67,28 @@ namespace System.ServiceModel.Channels
                }
 
                protected HttpTransportBindingElement (
-                       HttpTransportBindingElement other)
-                       : base (other)
+                       HttpTransportBindingElement elementToBeCloned)
+                       : base (elementToBeCloned)
                {
-                       allow_cookies = other.allow_cookies;
-                       bypass_proxy_on_local = other.bypass_proxy_on_local;
-                       unsafe_ntlm_auth = other.unsafe_ntlm_auth;
-                       use_default_proxy = other.use_default_proxy;
-                       keep_alive_enabled = other.keep_alive_enabled;
-                       max_buffer_size = other.max_buffer_size;
-                       host_cmp_mode = other.host_cmp_mode;
-                       proxy_address = other.proxy_address;
-                       realm = other.realm;
-                       transfer_mode = other.transfer_mode;
+                       allow_cookies = elementToBeCloned.allow_cookies;
+                       bypass_proxy_on_local = elementToBeCloned.bypass_proxy_on_local;
+                       unsafe_ntlm_auth = elementToBeCloned.unsafe_ntlm_auth;
+                       use_default_proxy = elementToBeCloned.use_default_proxy;
+                       keep_alive_enabled = elementToBeCloned.keep_alive_enabled;
+                       max_buffer_size = elementToBeCloned.max_buffer_size;
+                       host_cmp_mode = elementToBeCloned.host_cmp_mode;
+                       proxy_address = elementToBeCloned.proxy_address;
+                       realm = elementToBeCloned.realm;
+                       transfer_mode = elementToBeCloned.transfer_mode;
                        // FIXME: it does not look safe
-                       timeouts = other.timeouts;
-                       auth_scheme = other.auth_scheme;
-                       proxy_auth_scheme = other.proxy_auth_scheme;
-
-                       DecompressionEnabled = other.DecompressionEnabled;
-                       LegacyExtendedProtectionPolicy = other.LegacyExtendedProtectionPolicy;
-                       ExtendedProtectionPolicy = other.ExtendedProtectionPolicy;
-                       cookie_manager = other.cookie_manager;
+                       timeouts = elementToBeCloned.timeouts;
+                       auth_scheme = elementToBeCloned.auth_scheme;
+                       proxy_auth_scheme = elementToBeCloned.proxy_auth_scheme;
+
+                       DecompressionEnabled = elementToBeCloned.DecompressionEnabled;
+                       LegacyExtendedProtectionPolicy = elementToBeCloned.LegacyExtendedProtectionPolicy;
+                       ExtendedProtectionPolicy = elementToBeCloned.ExtendedProtectionPolicy;
+                       cookie_manager = elementToBeCloned.cookie_manager;
                }
 
                [DefaultValue (AuthenticationSchemes.Anonymous)]
index d281d484d8689e10310d8bc680b94ee6b7992d08..3d890b95142d29f5ba2e8d49730c6a6086843103 100644 (file)
@@ -47,10 +47,10 @@ namespace System.ServiceModel.Channels
                }
 
                protected HttpsTransportBindingElement (
-                       HttpsTransportBindingElement other)
-                       : base (other)
+                       HttpsTransportBindingElement elementToBeCloned)
+                       : base (elementToBeCloned)
                {
-                       req_cli_cert = other.req_cli_cert;
+                       req_cli_cert = elementToBeCloned.req_cli_cert;
                }
 
                public bool RequireClientCertificate {
index f67ce5dd8ad5a357f0d1408aec19137c4e16ac62..1b6be5ad60d66d7d4064dcf22255545d65abf0a7 100644 (file)
@@ -98,10 +98,10 @@ namespace System.ServiceModel.Channels
                        return OnGetBody<T> (GetReaderAtBodyContents ());
                }
 
-               public T GetBody<T> (XmlObjectSerializer xmlFormatter)
+               public T GetBody<T> (XmlObjectSerializer serializer)
                {
                        // FIXME: Somehow use OnGetBody() here as well?
-                       return (T)xmlFormatter.ReadObject (GetReaderAtBodyContents ());
+                       return (T)serializer.ReadObject (GetReaderAtBodyContents ());
                }
 
                protected virtual T OnGetBody<T> (XmlDictionaryReader reader)
@@ -369,13 +369,13 @@ namespace System.ServiceModel.Channels
 
                // 5)
                public static Message CreateMessage (MessageVersion version,
-                       string action, object body, XmlObjectSerializer xmlFormatter)
+                       string action, object body, XmlObjectSerializer serializer)
                {
                        return body == null ?
                                CreateMessage (version, action) :
                                CreateMessage (
                                        version, action,
-                                       new XmlObjectSerializerBodyWriter (body, xmlFormatter));
+                                       new XmlObjectSerializerBodyWriter (body, serializer));
                }
 
                // 6)
index bc3405e53412e455543ef1039a2ded8e49846225..9a40e499eb2806b29820caaace34b34d874d859a 100644 (file)
@@ -42,9 +42,9 @@ namespace System.ServiceModel.Channels
 
                [MonoTODO]
                public
-               MessageEncodingBindingElement (MessageEncodingBindingElement source)
+               MessageEncodingBindingElement (MessageEncodingBindingElement elementToBeCloned)
                {
-                       MessageVersion = source.MessageVersion;
+                       MessageVersion = elementToBeCloned.MessageVersion;
                }
 
                public abstract MessageEncoderFactory
@@ -52,11 +52,11 @@ namespace System.ServiceModel.Channels
 
                public abstract MessageVersion MessageVersion { get; set; }
 
-               public override T GetProperty<T> (BindingContext ctx)
+               public override T GetProperty<T> (BindingContext context)
                {
                        if (typeof (T) == typeof (MessageVersion))
                                return (T) (object) MessageVersion;
-                       return ctx.GetInnerProperty<T> ();
+                       return context.GetInnerProperty<T> ();
                }
 
 #if !MOBILE && !XAMMAC_4_5
index 3e809c4b1372773663015b841a8fa0ea60d86286..e8e10533584f1277fdcfea277cf69ca0bdb89415 100644 (file)
@@ -397,12 +397,12 @@ namespace System.ServiceModel.Channels
                        return GetDetail<T> (new DataContractSerializer (typeof (T)));
                }
 
-               public T GetDetail<T> (XmlObjectSerializer formatter)
+               public T GetDetail<T> (XmlObjectSerializer serializer)
                {
                        if (!HasDetail)
                                throw new InvalidOperationException ("This message does not have details.");
 
-                       return (T) formatter.ReadObject (GetReaderAtDetailContents ());
+                       return (T) serializer.ReadObject (GetReaderAtDetailContents ());
                }
 
                public XmlDictionaryReader GetReaderAtDetailContents ()
index 4e37df9c865837039543d01319d9fb10a582c0bf..4769523848907ce28b261a5a778a3612dcc393ef 100644 (file)
@@ -59,56 +59,56 @@ namespace System.ServiceModel.Channels
                        return CreateHeader (name, ns, value, default_must_understand);
                }
 
-               public static MessageHeader CreateHeader (string name, string ns, object value, bool must_understand)
+               public static MessageHeader CreateHeader (string name, string ns, object value, bool mustUnderstand)
                {
-                       return CreateHeader (name, ns, value, must_understand, default_actor);
+                       return CreateHeader (name, ns, value, mustUnderstand, default_actor);
                }
 
-               public static MessageHeader CreateHeader (string name, string ns, object value, XmlObjectSerializer formatter)
+               public static MessageHeader CreateHeader (string name, string ns, object value, XmlObjectSerializer serializer)
                {
-                       return CreateHeader (name, ns, value, formatter, default_must_understand, 
+                       return CreateHeader (name, ns, value, serializer, default_must_understand, 
                                             default_actor, default_relay);
                }
 
                public static MessageHeader CreateHeader (string name, string ns, object value, 
-                                                  bool must_understand, string actor)
+                                                  bool mustUnderstand, string actor)
                {
-                       return CreateHeader (name, ns, value, must_understand, actor, default_relay);
+                       return CreateHeader (name, ns, value, mustUnderstand, actor, default_relay);
                }
 
-               public static MessageHeader CreateHeader (string name, string ns, object value, XmlObjectSerializer formatter, 
-                                                  bool must_understand)
+               public static MessageHeader CreateHeader (string name, string ns, object value, XmlObjectSerializer serializer, 
+                                                  bool mustUnderstand)
                {
-                       return CreateHeader (name, ns, value, formatter, must_understand, default_actor, default_relay);
+                       return CreateHeader (name, ns, value, serializer, mustUnderstand, default_actor, default_relay);
                }
                
                public static MessageHeader CreateHeader (string name, string ns, object value, 
-                                                  bool must_understand, string actor, bool relay)
+                                                  bool mustUnderstand, string actor, bool relay)
                {
                        return CreateHeader (name, ns, value, new DataContractSerializer (value.GetType ()),
-                                       must_understand, actor, relay);
+                                       mustUnderstand, actor, relay);
                }
 
-               public static MessageHeader CreateHeader (string name, string ns, object value, XmlObjectSerializer formatter,
-                                                  bool must_understand, string actor)
+               public static MessageHeader CreateHeader (string name, string ns, object value, XmlObjectSerializer serializer,
+                                                  bool mustUnderstand, string actor)
                {
-                       return CreateHeader (name, ns, value, formatter, must_understand, actor, default_relay);
+                       return CreateHeader (name, ns, value, serializer, mustUnderstand, actor, default_relay);
                }
                
-               public static MessageHeader CreateHeader (string name, string ns, object value, XmlObjectSerializer formatter,
-                                                  bool must_understand, string actor, bool relay)
+               public static MessageHeader CreateHeader (string name, string ns, object value, XmlObjectSerializer serializer,
+                                                  bool mustUnderstand, string actor, bool relay)
                {
                        // FIXME: how to get IsReferenceParameter ?
-                       return new DefaultMessageHeader (name, ns, value, formatter, default_is_ref, must_understand, actor, relay);
+                       return new DefaultMessageHeader (name, ns, value, serializer, default_is_ref, mustUnderstand, actor, relay);
                }
 
-               public virtual bool IsMessageVersionSupported (MessageVersion version)
+               public virtual bool IsMessageVersionSupported (MessageVersion messageVersion)
                {
-                       if (version.Envelope == EnvelopeVersion.Soap12)
+                       if (messageVersion.Envelope == EnvelopeVersion.Soap12)
                                if (Actor == EnvelopeVersion.Soap11.NextDestinationActorValue)
                                        return false;
 
-                       if (version.Envelope == EnvelopeVersion.Soap11)
+                       if (messageVersion.Envelope == EnvelopeVersion.Soap11)
                                if (Actor == EnvelopeVersion.Soap12.NextDestinationActorValue ||
                                    Actor == EnvelopeVersion.Soap12UltimateReceiver)
                                        return false;
@@ -117,9 +117,9 @@ namespace System.ServiceModel.Channels
                        return true;
                }
 
-               protected abstract void OnWriteHeaderContents (XmlDictionaryWriter writer, MessageVersion version);
+               protected abstract void OnWriteHeaderContents (XmlDictionaryWriter writer, MessageVersion messageVersion);
 
-               protected virtual void OnWriteStartHeader (XmlDictionaryWriter writer, MessageVersion version)
+               protected virtual void OnWriteStartHeader (XmlDictionaryWriter writer, MessageVersion messageVersion)
                {
                        var dic = Constants.SoapDictionary;
                        XmlDictionaryString name, ns;
@@ -128,7 +128,7 @@ namespace System.ServiceModel.Channels
                                writer.WriteStartElement (prefix, name, ns);
                        else
                                writer.WriteStartElement (prefix, this.Name, this.Namespace);
-                       WriteHeaderAttributes (writer, version);
+                       WriteHeaderAttributes (writer, messageVersion);
                }
 
                public override string ToString ()
@@ -143,58 +143,58 @@ namespace System.ServiceModel.Channels
                        return sb.ToString ();
                }
 
-               public void WriteHeader (XmlDictionaryWriter writer, MessageVersion version)
+               public void WriteHeader (XmlDictionaryWriter writer, MessageVersion messageVersion)
                {
                        if (writer == null)
                                throw new ArgumentNullException ("writer is null.");
 
-                       if (version == null)
-                               throw new ArgumentNullException ("version is null.");
+                       if (messageVersion == null)
+                               throw new ArgumentNullException ("messageVersion is null.");
 
-                       if (version.Envelope == EnvelopeVersion.None)
+                       if (messageVersion.Envelope == EnvelopeVersion.None)
                                return;
 
-                       WriteStartHeader (writer, version);
-                       WriteHeaderContents (writer, version);
+                       WriteStartHeader (writer, messageVersion);
+                       WriteHeaderContents (writer, messageVersion);
 
                        writer.WriteEndElement ();
                }
 
-               public void WriteHeader (XmlWriter writer, MessageVersion version)
+               public void WriteHeader (XmlWriter writer, MessageVersion messageVersion)
                {
-                       WriteHeader (XmlDictionaryWriter.CreateDictionaryWriter (writer), version);
+                       WriteHeader (XmlDictionaryWriter.CreateDictionaryWriter (writer), messageVersion);
                }
 
-               protected void WriteHeaderAttributes (XmlDictionaryWriter writer, MessageVersion version)
+               protected void WriteHeaderAttributes (XmlDictionaryWriter writer, MessageVersion messageVersion)
                {
                        var dic = Constants.SoapDictionary;
                        if (Id != null)
                                writer.WriteAttributeString ("u", dic.Add ("Id"), dic.Add (Constants.WsuNamespace), Id);
                        if (!String.IsNullOrEmpty (Actor)) {
-                               if (version.Envelope == EnvelopeVersion.Soap11) 
-                                       writer.WriteAttributeString ("s", dic.Add ("actor"), dic.Add (version.Envelope.Namespace), Actor);
+                               if (messageVersion.Envelope == EnvelopeVersion.Soap11) 
+                                       writer.WriteAttributeString ("s", dic.Add ("actor"), dic.Add (messageVersion.Envelope.Namespace), Actor);
 
-                               if (version.Envelope == EnvelopeVersion.Soap12) 
-                                       writer.WriteAttributeString ("s", dic.Add ("role"), dic.Add (version.Envelope.Namespace), Actor);
+                               if (messageVersion.Envelope == EnvelopeVersion.Soap12) 
+                                       writer.WriteAttributeString ("s", dic.Add ("role"), dic.Add (messageVersion.Envelope.Namespace), Actor);
                        }
 
                        // mustUnderstand is the same across SOAP 1.1 and 1.2
                        if (MustUnderstand == true)
-                               writer.WriteAttributeString ("s", dic.Add ("mustUnderstand"), dic.Add (version.Envelope.Namespace), "1");
+                               writer.WriteAttributeString ("s", dic.Add ("mustUnderstand"), dic.Add (messageVersion.Envelope.Namespace), "1");
 
                        // relay is only available on SOAP 1.2
-                       if (Relay == true && version.Envelope == EnvelopeVersion.Soap12)
-                               writer.WriteAttributeString ("s", dic.Add ("relay"), dic.Add (version.Envelope.Namespace), "true");
+                       if (Relay == true && messageVersion.Envelope == EnvelopeVersion.Soap12)
+                               writer.WriteAttributeString ("s", dic.Add ("relay"), dic.Add (messageVersion.Envelope.Namespace), "true");
                }
 
-               public void WriteHeaderContents (XmlDictionaryWriter writer, MessageVersion version)
+               public void WriteHeaderContents (XmlDictionaryWriter writer, MessageVersion messageVersion)
                {
-                       this.OnWriteHeaderContents (writer, version);
+                       this.OnWriteHeaderContents (writer, messageVersion);
                }
 
-               public void WriteStartHeader (XmlDictionaryWriter writer, MessageVersion version)
+               public void WriteStartHeader (XmlDictionaryWriter writer, MessageVersion messageVersion)
                {
-                       this.OnWriteStartHeader (writer, version);
+                       this.OnWriteStartHeader (writer, messageVersion);
                }
 
                public override string Actor { get { return default_actor; }}
index fc4a8e139a1f6a933e750c2e87ee12226ac6df49..c08ef8697dd13e5cba749f5e94fc573d69450439 100644 (file)
@@ -72,9 +72,9 @@ namespace System.ServiceModel.Channels
                        l.Add (header);
                }
 
-               public void CopyHeaderFrom (Message m, int index)
+               public void CopyHeaderFrom (Message message, int headerIndex)
                {
-                       CopyHeaderFrom (m.Headers, index);
+                       CopyHeaderFrom (message.Headers, headerIndex);
                }
 
                public void Clear ()
@@ -82,25 +82,25 @@ namespace System.ServiceModel.Channels
                        l.Clear ();
                }
 
-               public void CopyHeaderFrom (MessageHeaders headers, int index)
+               public void CopyHeaderFrom (MessageHeaders collection, int headerIndex)
                {
-                       l.Add (headers [index]);
+                       l.Add (collection [headerIndex]);
                }
 
-               public void CopyHeadersFrom (Message m)
+               public void CopyHeadersFrom (Message message)
                {
-                       CopyHeadersFrom (m.Headers);
+                       CopyHeadersFrom (message.Headers);
                }
 
-               public void CopyHeadersFrom (MessageHeaders headers)
+               public void CopyHeadersFrom (MessageHeaders collection)
                {
-                       foreach (MessageHeaderInfo h in headers)
+                       foreach (MessageHeaderInfo h in collection)
                                l.Add (h);
                }
 
-               public void CopyTo (MessageHeaderInfo [] dst, int index)
+               public void CopyTo (MessageHeaderInfo [] array, int index)
                {
-                       l.CopyTo (dst, index);
+                       l.CopyTo (array, index);
                }
 
                public int FindHeader (string name, string ns)
@@ -203,11 +203,11 @@ namespace System.ServiceModel.Channels
                        return GetHeader<T> (idx, serializer);
                }
 
-               public XmlDictionaryReader GetReaderAtHeader (int index)
+               public XmlDictionaryReader GetReaderAtHeader (int headerIndex)
                {
-                       if (index >= l.Count)
-                               throw new ArgumentOutOfRangeException (String.Format ("Index is out of range. Current header count is {0}", index));
-                       MessageHeader item = (MessageHeader) l [index];
+                       if (headerIndex >= l.Count)
+                               throw new ArgumentOutOfRangeException (String.Format ("Index is out of range. Current header count is {0}", l.Count));
+                       MessageHeader item = (MessageHeader) l [headerIndex];
 
                        XmlReader reader =
                                item is MessageHeader.XmlMessageHeader ?
@@ -231,9 +231,9 @@ namespace System.ServiceModel.Channels
                        throw new NotImplementedException ();
                }
 
-               public void Insert (int index, MessageHeader header)
+               public void Insert (int headerIndex, MessageHeader header)
                {
-                       l.Insert (index, header);
+                       l.Insert (headerIndex, header);
                }
 
                public void RemoveAll (string name, string ns)
@@ -251,9 +251,9 @@ namespace System.ServiceModel.Channels
                                l.RemoveAt (l.Count - 1);
                }
 
-               public void RemoveAt (int index)
+               public void RemoveAt (int headerIndex)
                {
-                       l.RemoveAt (index);
+                       l.RemoveAt (headerIndex);
                }
 
                IEnumerator IEnumerable.GetEnumerator ()
@@ -261,48 +261,48 @@ namespace System.ServiceModel.Channels
                        return ((IEnumerable) l).GetEnumerator ();
                }
 
-               public void WriteHeader (int index, XmlDictionaryWriter writer)
+               public void WriteHeader (int headerIndex, XmlDictionaryWriter writer)
                {
                        if (version.Envelope == EnvelopeVersion.None)
                                return;
-                       WriteStartHeader (index, writer);
-                       WriteHeaderContents (index, writer);
+                       WriteStartHeader (headerIndex, writer);
+                       WriteHeaderContents (headerIndex, writer);
                        writer.WriteEndElement ();
                }
 
-               public void WriteHeader (int index, XmlWriter writer)
+               public void WriteHeader (int headerIndex, XmlWriter writer)
                {
-                       WriteHeader (index, XmlDictionaryWriter.CreateDictionaryWriter (writer));
+                       WriteHeader (headerIndex, XmlDictionaryWriter.CreateDictionaryWriter (writer));
                }
 
-               public void WriteHeaderContents (int index, XmlDictionaryWriter writer)
+               public void WriteHeaderContents (int headerIndex, XmlDictionaryWriter writer)
                {
-                       if (index > l.Count)
-                               throw new ArgumentOutOfRangeException ("There is no header at position " + index + ".");
+                       if (headerIndex > l.Count)
+                               throw new ArgumentOutOfRangeException ("There is no header at position " + headerIndex + ".");
                        
-                       MessageHeader h = l [index] as MessageHeader;
+                       MessageHeader h = l [headerIndex] as MessageHeader;
 
                        h.WriteHeaderContents (writer, version);
                }
 
-               public void WriteHeaderContents (int index, XmlWriter writer)
+               public void WriteHeaderContents (int headerIndex, XmlWriter writer)
                {
-                       WriteHeaderContents (index, XmlDictionaryWriter.CreateDictionaryWriter (writer));
+                       WriteHeaderContents (headerIndex, XmlDictionaryWriter.CreateDictionaryWriter (writer));
                }
 
-               public void WriteStartHeader (int index, XmlDictionaryWriter writer)
+               public void WriteStartHeader (int headerIndex, XmlDictionaryWriter writer)
                {
-                       if (index > l.Count)
-                               throw new ArgumentOutOfRangeException ("There is no header at position " + index + ".");
+                       if (headerIndex > l.Count)
+                               throw new ArgumentOutOfRangeException ("There is no header at position " + headerIndex + ".");
 
-                       MessageHeader h = l [index] as MessageHeader;
+                       MessageHeader h = l [headerIndex] as MessageHeader;
                        
                        h.WriteStartHeader (writer, version);
                }
 
-               public void WriteStartHeader (int index, XmlWriter writer)
+               public void WriteStartHeader (int headerIndex, XmlWriter writer)
                {
-                       WriteStartHeader (index, XmlDictionaryWriter.CreateDictionaryWriter (writer));
+                       WriteStartHeader (headerIndex, XmlDictionaryWriter.CreateDictionaryWriter (writer));
                }
 
                public string Action {
index f79b9e94c42f61c06a329b5385b6ede9a58bfd69..27f3ea130c75f2a4ab2ca895296566373566889e 100644 (file)
@@ -53,36 +53,36 @@ namespace System.ServiceModel.Channels {
                        this.addressing = addressing;
                }
                
-               public static MessageVersion CreateVersion (EnvelopeVersion envelope_version)
+               public static MessageVersion CreateVersion (EnvelopeVersion envelopeVersion)
                {
-                       return CreateVersion (envelope_version,
+                       return CreateVersion (envelopeVersion,
                                AddressingVersion.WSAddressing10);
                }
 
-               public static MessageVersion CreateVersion (EnvelopeVersion envelope_version,
-                                                           AddressingVersion addressing_version)
+               public static MessageVersion CreateVersion (EnvelopeVersion envelopeVersion,
+                                                           AddressingVersion addressingVersion)
                {
-                       if (envelope_version == EnvelopeVersion.None && addressing_version == AddressingVersion.None)
+                       if (envelopeVersion == EnvelopeVersion.None && addressingVersion == AddressingVersion.None)
                                return None;
-                       if (envelope_version == EnvelopeVersion.Soap11 && addressing_version == AddressingVersion.None)
+                       if (envelopeVersion == EnvelopeVersion.Soap11 && addressingVersion == AddressingVersion.None)
                                return Soap11;
-                       if (envelope_version == EnvelopeVersion.Soap12 && addressing_version == AddressingVersion.WSAddressing10)
+                       if (envelopeVersion == EnvelopeVersion.Soap12 && addressingVersion == AddressingVersion.WSAddressing10)
                                return Soap12WSAddressing10;
 
-                       if (envelope_version == EnvelopeVersion.Soap12 && addressing_version == AddressingVersion.None)
+                       if (envelopeVersion == EnvelopeVersion.Soap12 && addressingVersion == AddressingVersion.None)
                                return Soap12;
-                       if (envelope_version == EnvelopeVersion.Soap11 && addressing_version == AddressingVersion.WSAddressing10)
+                       if (envelopeVersion == EnvelopeVersion.Soap11 && addressingVersion == AddressingVersion.WSAddressing10)
                                return Soap11WSAddressing10;
-                       if (envelope_version == EnvelopeVersion.Soap11 && addressing_version == AddressingVersion.WSAddressingAugust2004)
+                       if (envelopeVersion == EnvelopeVersion.Soap11 && addressingVersion == AddressingVersion.WSAddressingAugust2004)
                                return Soap11WSAddressingAugust2004;
-                       if (envelope_version == EnvelopeVersion.Soap12 && addressing_version == AddressingVersion.WSAddressingAugust2004)
+                       if (envelopeVersion == EnvelopeVersion.Soap12 && addressingVersion == AddressingVersion.WSAddressingAugust2004)
                                return Soap12WSAddressingAugust2004;
-                       throw new ArgumentException (string.Format ("EnvelopeVersion {0} cannot be used with AddressingVersion {1}", envelope_version, addressing_version));
+                       throw new ArgumentException (string.Format ("EnvelopeVersion {0} cannot be used with AddressingVersion {1}", envelopeVersion, addressingVersion));
                }
 
-               public override bool Equals (object value)
+               public override bool Equals (object obj)
                {
-                       MessageVersion other = value as MessageVersion;
+                       MessageVersion other = obj as MessageVersion;
 
                        if (other == null)
                                return false;
index ae23b3e3336f50c4c44411d98975dd19faf3c1eb..ffcc6110be6b8219fe27b0aa7131899ebb060e9a 100644 (file)
@@ -531,29 +531,29 @@ namespace System.ServiceModel.Channels
 #endif
 
                public static SecurityBindingElement 
-                       CreateSecureConversationBindingElement (SecurityBindingElement binding)
+                       CreateSecureConversationBindingElement (SecurityBindingElement bootstrapSecurity)
                {
-                       return CreateSecureConversationBindingElement (binding, false);
+                       return CreateSecureConversationBindingElement (bootstrapSecurity, false);
                }
 
                public static SecurityBindingElement 
                        CreateSecureConversationBindingElement (
-                       SecurityBindingElement binding, bool requireCancellation)
+                       SecurityBindingElement bootstrapSecurity, bool requireCancellation)
                {
-                       return CreateSecureConversationBindingElement (binding, requireCancellation, null);
+                       return CreateSecureConversationBindingElement (bootstrapSecurity, requireCancellation, null);
                }
 
                public static SecurityBindingElement 
                        CreateSecureConversationBindingElement (
-                       SecurityBindingElement binding, bool requireCancellation,
-                       ChannelProtectionRequirements protectionRequirements)
+                       SecurityBindingElement bootstrapSecurity, bool requireCancellation,
+                       ChannelProtectionRequirements bootstrapProtectionRequirements)
                {
 #if !MOBILE && !XAMMAC_4_5
                        SymmetricSecurityBindingElement be =
                                new SymmetricSecurityBindingElement ();
                        be.ProtectionTokenParameters =
                                new SecureConversationSecurityTokenParameters (
-                                       binding, requireCancellation, protectionRequirements);
+                                       bootstrapSecurity, requireCancellation, bootstrapProtectionRequirements);
                        return be;
 #else
                        throw new NotImplementedException ();
index ae823e534ebd876c8672cf0708f3f2e2891886d6..e80c26c308fb39add3bfc8cd976478705923824f 100644 (file)
@@ -53,12 +53,12 @@ namespace System.ServiceModel.Channels
                }
 
                protected TcpTransportBindingElement (
-                       TcpTransportBindingElement other)
-                       : base (other)
+                       TcpTransportBindingElement elementToBeCloned)
+                       : base (elementToBeCloned)
                {
-                       listen_backlog = other.listen_backlog;
-                       port_sharing_enabled = other.port_sharing_enabled;
-                       pool.CopyPropertiesFrom (other.pool);
+                       listen_backlog = elementToBeCloned.listen_backlog;
+                       port_sharing_enabled = elementToBeCloned.port_sharing_enabled;
+                       pool.CopyPropertiesFrom (elementToBeCloned.pool);
                }
                
                public TcpConnectionPoolSettings ConnectionPoolSettings {
index deb4b4b49f5d28010a7de6eadcdb9edc65477eac..17f3a1c36d098b5a51cc2a79a544469502f4943e 100644 (file)
@@ -48,12 +48,12 @@ namespace System.ServiceModel.Channels
                }
 
                protected TransportBindingElement (
-                       TransportBindingElement other)
-                       : base (other)
+                       TransportBindingElement elementToBeCloned)
+                       : base (elementToBeCloned)
                {
-                       manual_addressing = other.manual_addressing;
-                       max_buffer_pool_size = other.max_buffer_pool_size;
-                       max_recv_message_size = other.max_recv_message_size;
+                       manual_addressing = elementToBeCloned.manual_addressing;
+                       max_buffer_pool_size = elementToBeCloned.max_buffer_pool_size;
+                       max_recv_message_size = elementToBeCloned.max_recv_message_size;
                }
 
                public virtual bool ManualAddressing {
index 4314c221857dbd41ee6dbd70cbdd1e00b6d785ee..db06df4e288e2f4718b7732662fb7101be641c3d 100644 (file)
@@ -51,17 +51,17 @@ namespace System.ServiceModel.Description
                }
 
                [MonoTODO]
-               protected ClientCredentials (ClientCredentials source)
+               protected ClientCredentials (ClientCredentials other)
                {
-                       userpass = source.userpass.Clone ();
-                       digest = source.digest.Clone ();
-                       initiator = source.initiator.Clone ();
-                       recipient = source.recipient.Clone ();
-                       windows = source.windows.Clone ();
+                       userpass = other.userpass.Clone ();
+                       digest = other.digest.Clone ();
+                       initiator = other.initiator.Clone ();
+                       recipient = other.recipient.Clone ();
+                       windows = other.windows.Clone ();
 #if !MOBILE
-                       issued_token = source.issued_token.Clone ();
-                       peer = source.peer.Clone ();
-                       support_interactive = source.support_interactive;
+                       issued_token = other.issued_token.Clone ();
+                       peer = other.peer.Clone ();
+                       support_interactive = other.support_interactive;
 #endif
                }
 
@@ -159,10 +159,10 @@ namespace System.ServiceModel.Description
 
                [MonoTODO]
                public virtual void ApplyClientBehavior (
-                       ServiceEndpoint endpoint, ClientRuntime behavior)
+                       ServiceEndpoint serviceEndpoint, ClientRuntime behavior)
                {
-                       if (endpoint == null)
-                               throw new ArgumentNullException ("endpoint");
+                       if (serviceEndpoint == null)
+                               throw new ArgumentNullException ("serviceEndpoint");
                        if (behavior == null)
                                throw new ArgumentNullException ("behavior");
 
index 9d12a23d4d2fb12f8c595c6678260f85a6d1b105..08327a5b50d6aeb2ca769534ff9a134790921dff 100644 (file)
@@ -35,22 +35,22 @@ namespace System.ServiceModel.Description
        public interface IContractBehavior
        {
                void AddBindingParameters (
-                       ContractDescription description,
+                       ContractDescription contractDescription,
                        ServiceEndpoint endpoint,
-                       BindingParameterCollection parameters);
+                       BindingParameterCollection bindingParameters);
 
                void ApplyClientBehavior (
-                       ContractDescription description,
+                       ContractDescription contractDescription,
                        ServiceEndpoint endpoint,
-                       ClientRuntime proxy);
+                       ClientRuntime clientRuntime);
 
                void ApplyDispatchBehavior (
-                       ContractDescription description,
+                       ContractDescription contractDescription,
                        ServiceEndpoint endpoint,
-                       DispatchRuntime dispatch);
+                       DispatchRuntime dispatchRuntime);
 
                void Validate (
-                       ContractDescription description,
+                       ContractDescription contractDescription,
                        ServiceEndpoint endpoint);
        }
 }
index 6eb47ec704580f8fb51f04d8a5ae42bc853ad216..773d2676dabe9cadae5e95ae7f8480c52bf13b84 100644 (file)
@@ -34,11 +34,11 @@ namespace System.ServiceModel.Description
        public interface IEndpointBehavior
        {
                void AddBindingParameters (ServiceEndpoint endpoint,
-                       BindingParameterCollection parameters);
-               void ApplyDispatchBehavior (ServiceEndpoint serviceEndpoint,
-                       EndpointDispatcher dispatcher);
-               void ApplyClientBehavior (ServiceEndpoint serviceEndpoint,
-                       ClientRuntime behavior);
-               void Validate (ServiceEndpoint serviceEndpoint);
+                       BindingParameterCollection bindingParameters);
+               void ApplyDispatchBehavior (ServiceEndpoint endpoint,
+                       EndpointDispatcher endpointDispatcher);
+               void ApplyClientBehavior (ServiceEndpoint endpoint,
+                       ClientRuntime clientRuntime);
+               void Validate (ServiceEndpoint endpoint);
        }
 }
index aa67812dfe50beddf7019f178cf4c51a0b017be1..5c887c122bea2aa77ab241f6b8122b7359b17145 100644 (file)
@@ -34,18 +34,18 @@ namespace System.ServiceModel.Description
        public interface IOperationBehavior
        {
                void AddBindingParameters (
-                       OperationDescription description,
-                       BindingParameterCollection parameters);
+                       OperationDescription operationDescription,
+                       BindingParameterCollection bindingParameters);
 
                void ApplyDispatchBehavior (
-                       OperationDescription description,
-                       DispatchOperation dispatch);
+                       OperationDescription operationDescription,
+                       DispatchOperation dispatchOperation);
 
                void ApplyClientBehavior (
-                       OperationDescription description,
-                       ClientOperation proxy);
+                       OperationDescription operationDescription,
+                       ClientOperation clientOperation);
 
                void Validate (
-                       OperationDescription description);
+                       OperationDescription operationDescription);
        }
 }
index 7c0afae785c632047907df2567ea18f4df6c9ac2..ddf9735e5dbbacd0d91f448d705768dd821cf0e2 100644 (file)
@@ -31,7 +31,7 @@ namespace System.ServiceModel.Dispatcher
 {
        public interface IClientMessageFormatter
        {
-               object DeserializeReply (Message message, object [] paremeters);
-               Message SerializeRequest (MessageVersion version, object [] inputs);
+               object DeserializeReply (Message message, object [] parameters);
+               Message SerializeRequest (MessageVersion messageVersion, object [] parameters);
        }
 }
index 5e331a0bd60cafab27689b7a8b395d3b3d9fe7ff..f1eb699517880beae462e99735d8179576ad1362 100644 (file)
@@ -31,7 +31,7 @@ namespace System.ServiceModel.Dispatcher
 {
        public interface IClientMessageInspector
        {
-               void AfterReceiveReply (ref Message message, object correlationState);
-               object BeforeSendRequest (ref Message message, IClientChannel channel);
+               void AfterReceiveReply (ref Message reply, object correlationState);
+               object BeforeSendRequest (ref Message request, IClientChannel channel);
        }
 }
index 3d8e71035a0f6c3a1bff8dd34dc527866e2b3131..41a1376f053884266ff70be148235365855c5d36 100644 (file)
@@ -75,30 +75,30 @@ namespace System.ServiceModel.Security.Tokens
                }
 
                public SecureConversationSecurityTokenParameters (
-                       SecurityBindingElement element)
-                       : this (element, true)
+                       SecurityBindingElement bootstrapSecurityBindingElement)
+                       : this (bootstrapSecurityBindingElement, true)
                {
                }
 
                public SecureConversationSecurityTokenParameters (
-                       SecurityBindingElement element,
+                       SecurityBindingElement bootstrapSecurityBindingElement,
                        bool requireCancellation)
-                       : this (element, requireCancellation, null)
+                       : this (bootstrapSecurityBindingElement, requireCancellation, null)
                {
                }
 
 #if !MOBILE && !XAMMAC_4_5
                public SecureConversationSecurityTokenParameters (
-                       SecurityBindingElement element,
+                       SecurityBindingElement bootstrapSecurityBindingElement,
                        bool requireCancellation,
-                       ChannelProtectionRequirements requirements)
+                       ChannelProtectionRequirements bootstrapProtectionRequirements)
                {
-                       this.element = element;
+                       this.element = bootstrapSecurityBindingElement;
                        this.cancellable = requireCancellation;
-                       if (requirements == null)
+                       if (bootstrapProtectionRequirements == null)
                                this.requirements = new ChannelProtectionRequirements (default_channel_protection_requirements);
                        else
-                               this.requirements = new ChannelProtectionRequirements (requirements);
+                               this.requirements = new ChannelProtectionRequirements (bootstrapProtectionRequirements);
                }
 #else
                internal SecureConversationSecurityTokenParameters (
index bd2b762d9473c68ccd3cdd9fc9f33d4b49d0281c..5b558599b08a5ed866d820a3a2a947a14bc6f7f6 100644 (file)
@@ -35,8 +35,8 @@ namespace System.ServiceModel
        public class ActionNotSupportedException : CommunicationException
        {
                public ActionNotSupportedException () : base () {}
-               public ActionNotSupportedException (string msg) : base (msg) {}
-               public ActionNotSupportedException (string msg, Exception inner) : base (msg, inner) {}
+               public ActionNotSupportedException (string message) : base (message) {}
+               public ActionNotSupportedException (string message, Exception innerException) : base (message, innerException) {}
                protected ActionNotSupportedException (SerializationInfo info, StreamingContext context) :
                        base (info, context) {}
        }
index 732a51022992a0a1e39175fe61a8555583908149..84b8f96db81167bdaab35788a4e94545208a1d82 100644 (file)
@@ -85,9 +85,9 @@ namespace System.ServiceModel
                        get { return Endpoint.Binding.OpenTimeout; }
                }
 
-               protected virtual void ApplyConfiguration (string endpointConfig)
+               protected virtual void ApplyConfiguration (string configurationName)
                {
-                       if (endpointConfig == null)
+                       if (configurationName == null)
                                return;
 
 #if MOBILE || XAMMAC_4_5
@@ -96,22 +96,22 @@ namespace System.ServiceModel
                                var cfg = new SilverlightClientConfigLoader ().Load (XmlReader.Create ("ServiceReferences.ClientConfig"));
 
                                SilverlightClientConfigLoader.ServiceEndpointConfiguration se = null;
-                               if (endpointConfig == "*")
+                               if (configurationName == "*")
                                        se = cfg.GetServiceEndpointConfiguration (Endpoint.Contract.Name);
                                if (se == null)
-                                       se = cfg.GetServiceEndpointConfiguration (endpointConfig);
+                                       se = cfg.GetServiceEndpointConfiguration (configurationName);
 
                                if (se.Binding != null && Endpoint.Binding == null)
                                        Endpoint.Binding = se.Binding;
                                else // ignore it
-                                       Console.WriteLine ("WARNING: Configured binding not found in configuration {0}", endpointConfig);
+                                       Console.WriteLine ("WARNING: Configured binding not found in configuration {0}", configurationName);
                                if (se.Address != null && Endpoint.Address == null)
                                        Endpoint.Address = se.Address;
                                else // ignore it
-                                       Console.WriteLine ("WARNING: Configured endpoint address not found in configuration {0}", endpointConfig);
+                                       Console.WriteLine ("WARNING: Configured endpoint address not found in configuration {0}", configurationName);
                        } catch (Exception) {
                                // ignore it.
-                               Console.WriteLine ("WARNING: failed to load endpoint configuration for {0}", endpointConfig);
+                               Console.WriteLine ("WARNING: failed to load endpoint configuration for {0}", configurationName);
                        }
 #else
 
@@ -120,7 +120,7 @@ namespace System.ServiceModel
                        ChannelEndpointElement endpoint = null;
 
                        foreach (ChannelEndpointElement el in client.Endpoints) {
-                               if (el.Contract == contractName && (endpointConfig == el.Name || endpointConfig == "*")) {
+                               if (el.Contract == contractName && (configurationName == el.Name || configurationName == "*")) {
                                        if (endpoint != null)
                                                throw new InvalidOperationException (String.Format ("More then one endpoint matching contract {0} was found.", contractName));
                                        endpoint = el;
@@ -128,7 +128,7 @@ namespace System.ServiceModel
                        }
 
                        if (endpoint == null)
-                               throw new InvalidOperationException (String.Format ("Client endpoint configuration '{0}' was not found in {1} endpoints.", endpointConfig, client.Endpoints.Count));
+                               throw new InvalidOperationException (String.Format ("Client endpoint configuration '{0}' was not found in {1} endpoints.", configurationName, client.Endpoints.Count));
 
                        var binding = String.IsNullOrEmpty (endpoint.Binding) ? null : ConfigUtil.CreateBinding (endpoint.Binding, endpoint.BindingConfiguration);
                        var contractType = ConfigUtil.GetTypeFromConfigString (endpoint.Contract, NamedConfigCategory.Contract);
@@ -298,23 +298,23 @@ namespace System.ServiceModel
                }
 
                protected void InitializeEndpoint (
-                       string endpointConfigurationName,
+                       string configurationName,
                        EndpointAddress remoteAddress)
                {
                        InitializeEndpoint (CreateDescription ());
                        if (remoteAddress != null)
                                service_endpoint.Address = remoteAddress;
-                       ApplyConfiguration (endpointConfigurationName);
+                       ApplyConfiguration (configurationName);
                }
 
                protected void InitializeEndpoint (Binding binding,
-                       EndpointAddress remoteAddress)
+                       EndpointAddress address)
                {
                        InitializeEndpoint (CreateDescription ());
                        if (binding != null)
                                service_endpoint.Binding = binding;
-                       if (remoteAddress != null)
-                               service_endpoint.Address = remoteAddress;
+                       if (address != null)
+                               service_endpoint.Address = address;
                }
 
                protected void InitializeEndpoint (ServiceEndpoint endpoint)
index 1af7625027ecea7470b966e0a0c214edbdb31571..0f6560c743f6dec1e8d53e34efbeca3bf3b40dba 100644 (file)
@@ -46,12 +46,12 @@ namespace System.ServiceModel
                {
                }
 
-               protected ChannelFactory (Type type)
+               protected ChannelFactory (Type channelType)
                {
-                       if (type == null)
-                               throw new ArgumentNullException ("type");
-                       if (!type.IsInterface)
-                               throw new InvalidOperationException ("The type argument to the generic ChannelFactory constructor must be an interface type.");
+                       if (channelType == null)
+                               throw new ArgumentNullException ("channelType");
+                       if (!channelType.IsInterface)
+                               throw new InvalidOperationException ("The channelType argument to the generic ChannelFactory constructor must be an interface type.");
 
                        InitializeEndpoint (CreateDescription ());
                }
index a41db9ad05281e5248f4d20f1493d4e3f8c07e63..9acde8e4f9c161f533a3b37c8c361a614ac8dc87 100644 (file)
@@ -34,8 +34,8 @@ namespace System.ServiceModel {
        public class CommunicationException : SystemException
        {
                public CommunicationException () : base () {}
-               public CommunicationException (string msg) : base (msg) {}
-               public CommunicationException (string msg, Exception inner) : base (msg, inner) {}
+               public CommunicationException (string message) : base (message) {}
+               public CommunicationException (string message, Exception innerException) : base (message, innerException) {}
                protected CommunicationException (SerializationInfo info, StreamingContext context)
                        : base (info, context) {}
        }
index 720d23eb9c60b842052935199dcab533ce226fad..57f814c2a93536b654bbe17ff0bc12221d9453d4 100644 (file)
@@ -34,9 +34,9 @@ namespace System.ServiceModel {
        public class CommunicationObjectAbortedException : CommunicationException
        {
                public CommunicationObjectAbortedException () : base () {}
-               public CommunicationObjectAbortedException (string msg) : base (msg) {}
-               public CommunicationObjectAbortedException (string msg, Exception inner)
-                       : base (msg, inner) {}          
+               public CommunicationObjectAbortedException (string message) : base (message) {}
+               public CommunicationObjectAbortedException (string message, Exception innerException)
+                       : base (message, innerException) {}             
                protected CommunicationObjectAbortedException (SerializationInfo info,
                                               StreamingContext context)
                        : base (info, context) {}
index c6fb51ee968da8915ff0e201896721e0f03e208c..6538d6a338923150ce0e060771e9f899de4be6f2 100644 (file)
@@ -34,9 +34,9 @@ namespace System.ServiceModel {
        public class CommunicationObjectFaultedException : CommunicationException
        {
                public CommunicationObjectFaultedException () : base () {}
-               public CommunicationObjectFaultedException (string msg) : base (msg) {}
-               public CommunicationObjectFaultedException (string msg, Exception inner)
-                       : base (msg, inner) {}
+               public CommunicationObjectFaultedException (string message) : base (message) {}
+               public CommunicationObjectFaultedException (string message, Exception innerException)
+                       : base (message, innerException) {}
                protected CommunicationObjectFaultedException (SerializationInfo info, StreamingContext context)
                        : base (info, context) {}
        }
index 9c9b76aec61ac33aae7400c40f01df1c6004c1b3..fb4d18dc563450e5fe7312077c7ad5df1c14c8a5 100644 (file)
@@ -45,12 +45,12 @@ namespace System.ServiceModel
                        Initialize (identity);
                }
 
-               public DnsEndpointIdentity (string dns)
-                       : this (Claim.CreateDnsClaim (dns))
+               public DnsEndpointIdentity (string dnsName)
+                       : this (Claim.CreateDnsClaim (dnsName))
                {
                }
 #else
-               public DnsEndpointIdentity (string dns)
+               public DnsEndpointIdentity (string dnsName)
                {
                        throw new NotImplementedException ();
                }
index f437b1a495b5b43cbabf5fca29b4e8204be77da8..64ce85812b5dabce76d928c81a1a802369c78231 100644 (file)
@@ -34,71 +34,71 @@ namespace System.ServiceModel
 {
        public class DuplexClientBase<TChannel> : ClientBase<TChannel> where TChannel : class
        {
-               protected DuplexClientBase (object instance)
-                       : this (new InstanceContext (instance), (Binding) null, null)
+               protected DuplexClientBase (object callbackInstance)
+                       : this (new InstanceContext (callbackInstance), (Binding) null, null)
                {
                }
 
-               protected DuplexClientBase (object instance,
-                       Binding binding, EndpointAddress address)
-                       : this (new InstanceContext (instance), binding, address)
+               protected DuplexClientBase (object callbackInstance,
+                       Binding binding, EndpointAddress remoteAddress)
+                       : this (new InstanceContext (callbackInstance), binding, remoteAddress)
                {
                }
 
-               protected DuplexClientBase (object instance,
-                       string configurationName)
-                       : this (new InstanceContext (instance), configurationName)
+               protected DuplexClientBase (object callbackInstance,
+                       string endpointConfigurationName)
+                       : this (new InstanceContext (callbackInstance), endpointConfigurationName)
                {
                }
 
-               protected DuplexClientBase (object instance,
-                       string bindingConfigurationName, EndpointAddress address)
-                       : this (new InstanceContext (instance), bindingConfigurationName, address)
+               protected DuplexClientBase (object callbackInstance,
+                       string bindingConfigurationName, EndpointAddress remoteAddress)
+                       : this (new InstanceContext (callbackInstance), bindingConfigurationName, remoteAddress)
                {
                }
 
-               protected DuplexClientBase (object instance,
+               protected DuplexClientBase (object callbackInstance,
                        string endpointConfigurationName, string remoteAddress)
-                       : this (new InstanceContext (instance), endpointConfigurationName, remoteAddress)
+                       : this (new InstanceContext (callbackInstance), endpointConfigurationName, remoteAddress)
                {
                }
 
-               protected DuplexClientBase (InstanceContext instance)
-                       : base (instance)
+               protected DuplexClientBase (InstanceContext callbackInstance)
+                       : base (callbackInstance)
                {
                }
 
-               protected DuplexClientBase (InstanceContext instance,
-                       Binding binding, EndpointAddress address)
-                       : base (instance, binding, address)
+               protected DuplexClientBase (InstanceContext callbackInstance,
+                       Binding binding, EndpointAddress remoteAddress)
+                       : base (callbackInstance, binding, remoteAddress)
                {
                }
 
-               protected DuplexClientBase (InstanceContext instance,
-                       string configurationName)
-                       : base (instance, configurationName)
+               protected DuplexClientBase (InstanceContext callbackInstance,
+                       string endpointConfigurationName)
+                       : base (callbackInstance, endpointConfigurationName)
                {
                }
 
-               protected DuplexClientBase (InstanceContext instance,
+               protected DuplexClientBase (InstanceContext callbackInstance,
                        string endpointConfigurationName, string remoteAddress)
-                       : base (instance, endpointConfigurationName, remoteAddress)
+                       : base (callbackInstance, endpointConfigurationName, remoteAddress)
                {
                }
 
-               protected DuplexClientBase (InstanceContext instance,
-                       string configurationName, EndpointAddress address)
-                       : base (instance, configurationName, address)
+               protected DuplexClientBase (InstanceContext callbackInstance,
+                       string endpointConfigurationName, EndpointAddress address)
+                       : base (callbackInstance, endpointConfigurationName, address)
                {
                }
 
-               protected DuplexClientBase (object instance, ServiceEndpoint endpoint)
-                       : this (new InstanceContext (instance), endpoint)
+               protected DuplexClientBase (object callbackInstance, ServiceEndpoint endpoint)
+                       : this (new InstanceContext (callbackInstance), endpoint)
                {
                }
 
-               protected DuplexClientBase (InstanceContext instance, ServiceEndpoint endpoint)
-                       : base (instance, endpoint)
+               protected DuplexClientBase (InstanceContext callbackInstance, ServiceEndpoint endpoint)
+                       : base (callbackInstance, endpoint)
                {
                }
 
index 737bad6244d948288fc0c5f6fc1e5dbab0bf658d..1740e4d99066ab81ce59ebfa32cce5e3c797bcfa 100644 (file)
@@ -70,11 +70,11 @@ namespace System.ServiceModel
                {
                }
 
-               public EndpointAddress (Uri uri, params AddressHeader [] headers)
-                       : this (uri, null, new AddressHeaderCollection (headers), null, null) {}
+               public EndpointAddress (Uri uri, params AddressHeader [] addressHeaders)
+                       : this (uri, null, new AddressHeaderCollection (addressHeaders), null, null) {}
 
-               public EndpointAddress (Uri uri, EndpointIdentity identity, params AddressHeader [] headers)
-                       : this (uri, identity, new AddressHeaderCollection (headers), null, null) {}
+               public EndpointAddress (Uri uri, EndpointIdentity identity, params AddressHeader [] addressHeaders)
+                       : this (uri, identity, new AddressHeaderCollection (addressHeaders), null, null) {}
 
                public EndpointAddress (Uri uri, EndpointIdentity identity, AddressHeaderCollection headers)
                        : this (uri, identity, headers, null, null) {}
index a3b644824598d30c3f8db1a4c29a86a43f734d6e..fc44796f7c9d0f93dd332b6f2f295fe01f84ea26 100644 (file)
@@ -34,8 +34,8 @@ namespace System.ServiceModel {
        public class EndpointNotFoundException : CommunicationException
        {
                public EndpointNotFoundException () : base () {}
-               public EndpointNotFoundException (string msg) : base (msg) {}
-               public EndpointNotFoundException (string msg, Exception inner) : base (msg, inner) {}
+               public EndpointNotFoundException (string message) : base (message) {}
+               public EndpointNotFoundException (string message, Exception innerException) : base (message, innerException) {}
                protected EndpointNotFoundException (SerializationInfo info, StreamingContext context) :
                        base (info, context) {}
        }
index c33159baca43a21195cdfa08d0cdff181bc02b3f..a2b47aa4f6a4e482871c79a28a272847e63f002b 100644 (file)
@@ -42,16 +42,16 @@ namespace System.ServiceModel
                {
                }
 
-               public FaultCode (string name, FaultCode subcode)
-                       : this (name, String.Empty, subcode)
+               public FaultCode (string name, FaultCode subCode)
+                       : this (name, String.Empty, subCode)
                {
                }
 
-               public FaultCode (string name, string ns, FaultCode subcode)
+               public FaultCode (string name, string ns, FaultCode subCode)
                {
                        this.name = name;
                        this.ns = ns;
-                       this.subcode = subcode;
+                       this.subcode = subCode;
                }
 
                public bool IsPredefinedFault {
@@ -78,9 +78,9 @@ namespace System.ServiceModel
                        get { return subcode; }
                }
 
-               public static FaultCode CreateReceiverFaultCode (FaultCode subcode)
+               public static FaultCode CreateReceiverFaultCode (FaultCode subCode)
                {
-                       return new FaultCode ("Receiver", subcode);
+                       return new FaultCode ("Receiver", subCode);
                }
 
                public static FaultCode CreateReceiverFaultCode (string name, string ns)
@@ -88,9 +88,9 @@ namespace System.ServiceModel
                        return CreateReceiverFaultCode (new FaultCode (name, ns));
                }
                
-               public static FaultCode CreateSenderFaultCode (FaultCode subcode)
+               public static FaultCode CreateSenderFaultCode (FaultCode subCode)
                {
-                       return new FaultCode ("Sender", subcode);
+                       return new FaultCode ("Sender", subCode);
                }
 
                public static FaultCode CreateSenderFaultCode (string name, string ns)
index 5e06e2f1287096be96fa594acaf68f370f43c00b..05b3af01caf8117bb1e39b4eae01a04e70323469 100644 (file)
@@ -100,7 +100,7 @@ namespace System.ServiceModel
                }
 
                [MonoTODO]
-               public static FaultException CreateFault (MessageFault fault,  params Type [] details)
+               public static FaultException CreateFault (MessageFault messageFault,  params Type [] faultDetailTypes)
                {
                        throw new NotImplementedException ();
                }
index fe787f2312950d03954a452f7705fa63b8b93786..eb0f348ffdbbcc036bca0812ef22c152694c9a72 100644 (file)
@@ -34,8 +34,8 @@ namespace System.ServiceModel {
        public class InvalidMessageContractException : SystemException
        {
                public InvalidMessageContractException () : base () {}
-               public InvalidMessageContractException (string msg) : base (msg) {}
-               public InvalidMessageContractException (string msg, Exception inner) : base (msg, inner) {}
+               public InvalidMessageContractException (string message) : base (message) {}
+               public InvalidMessageContractException (string message, Exception innerException) : base (message, innerException) {}
                protected InvalidMessageContractException (SerializationInfo info, StreamingContext context) :
                        base (info, context) {}
        }
index b47c54750f5cefe905cb954958bf4e4e0e4f5db7..376c3861ad12887081c0db2a5f8be274bd7fda8a 100644 (file)
@@ -35,8 +35,8 @@ namespace System.ServiceModel {
        public class MessageHeaderException : ProtocolException
        {
                public MessageHeaderException () : this ("Message header exception") {}
-               public MessageHeaderException (string msg) : this (msg, null) {}
-               public MessageHeaderException (string msg, Exception inner) : base (msg, inner) {}
+               public MessageHeaderException (string message) : this (message, null) {}
+               public MessageHeaderException (string message, Exception innerException) : base (message, innerException) {}
                protected MessageHeaderException (SerializationInfo info, StreamingContext context) :
                        base (info, context)
                {
index 04814785c61ba95cfe1be7ccc63456fb658038c1..e6d17aab279782f73799da0573c5c36337057438 100644 (file)
@@ -53,10 +53,10 @@ namespace System.ServiceModel
                {
                }
 
-               public MessageHeader (T content, bool must_understand, string actor, bool relay)
+               public MessageHeader (T content, bool mustUnderstand, string actor, bool relay)
                {
                        this.content = content;
-                       this.must_understand = must_understand;
+                       this.must_understand = mustUnderstand;
                        this.actor = actor;
                        this.relay = relay;
                }
index e2fc290816d06c2b9c9bfca9770aee980eb49526..4a2a89d205777f2dc178410da25623b9eb5f1eec 100644 (file)
@@ -34,9 +34,9 @@ namespace System.ServiceModel {
        public class ProtocolException : CommunicationException
        {
                public ProtocolException () : base () {}
-               public ProtocolException (string msg) : base (msg) {}
-               public ProtocolException (string msg, Exception inner)
-                       : base (msg, inner) {}          
+               public ProtocolException (string message) : base (message) {}
+               public ProtocolException (string message, Exception innerException)
+                       : base (message, innerException) {}             
                protected ProtocolException (SerializationInfo info,
                                          StreamingContext context)
                        : base (info, context) {}
index adf08d2a071072488a85597f224b0a22cc5936f0..0407be88306732fe349607fff9c62162c0480a9b 100644 (file)
@@ -34,9 +34,9 @@ namespace System.ServiceModel {
        public class QuotaExceededException : SystemException
        {
                public QuotaExceededException () : base () {}
-               public QuotaExceededException (string msg) : base (msg) {}
-               public QuotaExceededException (string msg, Exception inner)
-                       : base (msg, inner) {}          
+               public QuotaExceededException (string message) : base (message) {}
+               public QuotaExceededException (string message, Exception innerException)
+                       : base (message, innerException) {}             
                protected QuotaExceededException (SerializationInfo info,
                                               StreamingContext context)
                        : base (info, context) {}
index f38f3125209f24612b966381702b5d35c3004ca1..c96b274e2af3050d17895a7c639cf7d06db913d5 100644 (file)
@@ -34,9 +34,9 @@ namespace System.ServiceModel {
        public class ServerTooBusyException : CommunicationException
        {
                public ServerTooBusyException () : base () {}
-               public ServerTooBusyException (string msg) : base (msg) {}
-               public ServerTooBusyException (string msg, Exception inner)
-                       : base (msg, inner) {}          
+               public ServerTooBusyException (string message) : base (message) {}
+               public ServerTooBusyException (string message, Exception innerException)
+                       : base (message, innerException) {}             
                protected ServerTooBusyException (SerializationInfo info,
                                               StreamingContext context)
                        : base (info, context) {}
index 6fe64902d4ce30ed2ce3013cd2db8740c19748e6..a55841387a817df5fff54780e40bcb701f6ce399 100644 (file)
@@ -34,9 +34,9 @@ namespace System.ServiceModel {
        public class ServiceActivationException : CommunicationException
        {
                public ServiceActivationException () : base () {}
-               public ServiceActivationException (string msg) : base (msg) {}
-               public ServiceActivationException (string msg, Exception inner)
-                       : base (msg, inner) {}          
+               public ServiceActivationException (string message) : base (message) {}
+               public ServiceActivationException (string message, Exception innerException)
+                       : base (message, innerException) {}             
                protected ServiceActivationException (SerializationInfo info,
                                               StreamingContext context)
                        : base (info, context) {}
index 396579fd2555c54aab9803f9eb3b90604c0dd641..4381d758cfc854e047c3baa368ddcf19350da01c 100644 (file)
@@ -45,12 +45,12 @@ namespace System.ServiceModel
                        Initialize (identity);
                }
 
-               public SpnEndpointIdentity (string spn)
-                       : this (Claim.CreateSpnClaim (spn))
+               public SpnEndpointIdentity (string spnName)
+                       : this (Claim.CreateSpnClaim (spnName))
                {
                }
 #else
-               public SpnEndpointIdentity (string spn)
+               public SpnEndpointIdentity (string spnName)
                {
                        throw new NotImplementedException ();
                }
index e53d72009a66a6c7591354242e2b7d8a20997dfb..93863a78e5f54876595ff8535113c2eae8589a6d 100644 (file)
@@ -45,12 +45,12 @@ namespace System.ServiceModel
                        Initialize (identity);
                }
 
-               public UpnEndpointIdentity (string upn)
-                       : this (Claim.CreateUpnClaim (upn))
+               public UpnEndpointIdentity (string upnName)
+                       : this (Claim.CreateUpnClaim (upnName))
                {
                }
 #else
-               public UpnEndpointIdentity (string upn)
+               public UpnEndpointIdentity (string upnName)
                {
                        throw new NotImplementedException ();
                }
index 976dc6728eac0dd5c1b272859bdae78a2a787ecb..f43655c573616811d5c737923109c124ff68edec 100644 (file)
@@ -129,7 +129,6 @@ namespace MonoTests.System.ServiceModel.MetadataTests {
                                AuthenticationSchemes.Ntlm, label);
                }
 
-#if NET_4_5
                [Test]
                public virtual void BasicHttps ()
                {
@@ -179,7 +178,6 @@ namespace MonoTests.System.ServiceModel.MetadataTests {
                                WSMessageEncoding.Text, HttpClientCredentialType.None,
                                AuthenticationSchemes.Anonymous, label);
                }
-#endif
                
                [Test]
                public virtual void NetTcp ()
index e04de3e58968947d49fc44b80ac83be916ae00d4..ab336b3c0500b53f17ba6bcb10a32e67664c140c 100644 (file)
@@ -136,7 +136,6 @@ namespace MonoTests.System.ServiceModel.MetadataTests {
                        return exporter.GetGeneratedMetadata ();
                }
                
-#if NET_4_5
                [MetadataSample]
                public static MetadataSet BasicHttps ()
                {
@@ -197,7 +196,6 @@ namespace MonoTests.System.ServiceModel.MetadataTests {
                        
                        return exporter.GetGeneratedMetadata ();
                }
-#endif
                
                [MetadataSample]
                public static MetadataSet NetTcp ()
index 3901a55afcd66efc16d509179183619a08f15916..b2193a91ba05029e967643024c803ee7a21de3f3 100644 (file)
@@ -68,9 +68,9 @@ namespace MonoTests.System.Threading.Tasks.Dataflow {
                        for (int i = 0; i < array.Length; ++i)
                                Assert.IsTrue (block.Post (i), "Not accepted");
 
-                       Thread.Sleep (300);
+                       Thread.Sleep (600);
                        block.LinkTo (action);
-                       Thread.Sleep (100);
+                       Thread.Sleep (300);
 
                        CollectionAssert.AreEqual (new[] { 0, -1, -2, -3, -4, -5, -6, -7, -8, -9 }, array);
                }
index 06ee42a1a11954ad135e2bceda783c3e00a6beec..a88bfa88c0efb44c29e23019914ba4b46a2ee29b 100644 (file)
@@ -169,7 +169,6 @@ namespace MonoTests.System.Web.Security
                        }
                }
 
-#if NET_4_5
                [Test]
                public void Protect ()
                {
@@ -200,6 +199,5 @@ namespace MonoTests.System.Web.Security
                                MachineKey.Unprotect (encryptedBytes, oneUsage), 
                                "Single purpose working when multiple supplied");
                }
-#endif
        }
 }
index 4ace2ca1b3721eb2099edabdd4f8e152cca3d218..b9900b94a5f8cd1594b9ae10604353e075c97144 100644 (file)
@@ -1,4 +1,3 @@
-#if NET_4_5
 
 using System.ComponentModel.DataAnnotations;
 using System.Linq;
@@ -137,4 +136,3 @@ namespace MonoTests.System.Web.Security {
                }
        }
 }
-#endif
index 9ae8aae05541ffcfd3b32b09fcdde4b773eb7273..192623ce4c4abca6f0289beb257f1f22833f5627 100644 (file)
@@ -26,7 +26,6 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_4_5
 
 using System;
 using System.Threading.Tasks;
@@ -115,4 +114,3 @@ namespace MonoTests.System.Web
        }
 }
 
-#endif
index 50afda19bcb9cc67595c47edda027a42d7467236..bfd5b216249c9ad08bf01758522b4fb4fc712b19 100644 (file)
@@ -26,7 +26,6 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_4_5
 
 using System;
 using System.IO;
@@ -129,4 +128,3 @@ namespace MonoTests.System.Web
        }
 }
 
-#endif
index 301a2988a3c10309c4ccfb8f74c79524c2ac8e08..05a67e4da0493a6ab3bffc6b9107b1891afcccc6 100644 (file)
@@ -26,7 +26,6 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_4_5
 
 using System;
 using System.Threading;
@@ -331,4 +330,3 @@ namespace MonoTests.System.Web
        }
 }
 
-#endif
index 16c46b496f4ce7a996bdbf568db76d706bd7e52a..26f461aeb30ff94cdb2f6dea7afffb0ae06499e8 100644 (file)
@@ -15,10 +15,8 @@ using System.Text;
 using System.Xml;\r
 using System.Xml.Schema;\r
 using System.Xml.XPath;\r
-#if NET_4_5\r
 using System.Threading;\r
 using System.Threading.Tasks;\r
-#endif\r
 \r
 using NUnit.Framework;\r
 \r
@@ -2298,7 +2296,6 @@ namespace MonoTests.System.Xml
                        Assert.AreEqual ((UInt64) 1, xr.ReadContentAs (typeof (UInt64), null), "#8");\r
                }\r
 \r
-#if NET_4_5\r
                [Test]\r
                [ExpectedException(typeof(InvalidOperationException))]\r
                public void MustSetAsyncFlag ()\r
@@ -2347,6 +2344,5 @@ namespace MonoTests.System.Xml
                        if (task.Result != null)\r
                                throw task.Result;\r
                }\r
-#endif\r
        }\r
 }\r
index effd9df94fe506380243727a24bcdf30a8449e3d..768cd5671dac943f4f59ee39dbed06dedf1daabe 100644 (file)
@@ -419,7 +419,6 @@ namespace MonoTests.System.Xml
                        Assert.AreEqual ("urn:foo", r.BaseURI);
                }
 
-#if NET_4_5
                [Test]
                [ExpectedException (typeof (XmlException))]
                public void ReadonlyAsync ()
@@ -444,6 +443,5 @@ namespace MonoTests.System.Xml
                        var r2 = XmlReader.Create (r, c);
                        Assert.IsTrue (r2.Settings.Async);
                }
-#endif
        }
 }
index df9756ee8f17739f224b7c92ebc770dc481bef09..15b20974487f087fc833d2132fa1c5de6df42d22 100644 (file)
@@ -103,7 +103,6 @@ namespace MonoTests.System.Xml {
                        Assert.IsTrue (u2.IsAbsoluteUri, "null,absolute/file");
                }
 
-#if NET_4_5
                class AsyncXmlResolver : XmlResolver
                {
                        public override object GetEntity (Uri absoluteUri, string role, Type ofObjectToReturn)
@@ -121,6 +120,5 @@ namespace MonoTests.System.Xml {
                        var uri = new Uri ("http://www.mono-project.com");
                        ar.GetEntityAsync (uri, null, typeof(string));
                }
-#endif
        }
 }
index 8f2de60a83892664ac61f5cb90d72dc37813427d..493bc6a8ad04504160745edfb05ef59ca5cc06d9 100644 (file)
@@ -124,7 +124,6 @@ namespace MonoTests.System.Xml
                        Assert.IsTrue (site, "Site-2");
                }
 
-#if NET_4_5
                [Test]
                [Category("Async")]
                public void TestAsync ()
@@ -139,7 +138,6 @@ namespace MonoTests.System.Xml
                        Assert.That (task.Wait (3000));
                        Assert.IsInstanceOfType (typeof (Stream), task.Result);
                }
-#endif
 
        }
 }
index e62e8cebad0d717565a4bfb6ae35bd4c28ec7130..f637e8cc326abd7c019506a39af0ed43e59ad850 100644 (file)
@@ -10,9 +10,7 @@ using System;
 using System.IO;\r
 using System.Xml;\r
 using NUnit.Framework;\r
-#if NET_4_5\r
 using System.Reflection;\r
-#endif\r
 \r
 namespace MonoTests.System.Xml\r
 {\r
@@ -98,7 +96,6 @@ namespace MonoTests.System.Xml
                        Assert.AreEqual ("view:Standard.xslt", uri.AbsoluteUri, "#2");\r
                }\r
 \r
-#if NET_4_5\r
                [Test]\r
                public void TestAsync ()\r
                {\r
@@ -126,6 +123,5 @@ namespace MonoTests.System.Xml
                                Assert.IsTrue (ex is XmlException);\r
                        }\r
                }\r
-#endif\r
        }\r
 }\r
index f70d43bd46d6e27ffd6c510d897722d2af9e4e34..3ee725dff252e037feb6f562b65756bf7ee8b961 100644 (file)
@@ -40,9 +40,7 @@ namespace MonoTests.System.Xml
                        Assert.AreEqual (false, s.NewLineOnAttributes);
                        Assert.AreEqual (false, s.OmitXmlDeclaration);
                        Assert.AreEqual (NewLineHandling.Replace, s.NewLineHandling);
-#if NET_4_5
                        Assert.IsFalse (s.Async);
-#endif
                }
 
                [Test]
@@ -381,7 +379,6 @@ namespace MonoTests.System.Xml
                        Assert.AreEqual (xml, sw.ToString ());
                }
 
-#if NET_4_5
                [Test]
                [ExpectedException (typeof (XmlException))]
                public void ReadonlyAsync ()
@@ -408,7 +405,6 @@ namespace MonoTests.System.Xml
                        var w2 = XmlWriter.Create (w, c);
                        Assert.IsTrue (w2.Settings.Async);
                }
-#endif
 
        }
 }
index dc395b7d110e122b8dcf779cc8490f9e24ffb6e7..5415ff8e50a4beb760cc5825406fd6e49e7a3989 100644 (file)
@@ -2084,7 +2084,6 @@ namespace MonoTests.System.Xml.Linq
                        public XElement Content;
                }
 
-#if NET_4_5
                [Test]
                // Bug #12571
                public void DeserializeXElement ()
@@ -2099,7 +2098,6 @@ namespace MonoTests.System.Xml.Linq
                        var xe = (SerializableClass)res;
                        Assert.AreEqual (xe.Content.ToString (), "<Data />", "#3");
                }
-#endif
 
                [Test] // Bug #20151
                public void XElementFromArrayWithNullValuesAsObject ()
index efed94f85503853ebcb46d07f6d5655dda3ffd95..705cd5d0206658a1bb3b900c3e98e4951560ecd5 100644 (file)
@@ -52,13 +52,13 @@ namespace System.IO.Compression
                bool disposed;
                DeflateStreamNative native;
 
-               public DeflateStream (Stream compressedStream, CompressionMode mode) :
-                       this (compressedStream, mode, false, false)
+               public DeflateStream (Stream stream, CompressionMode mode) :
+                       this (stream, mode, false, false)
                {
                }
 
-               public DeflateStream (Stream compressedStream, CompressionMode mode, bool leaveOpen) :
-                       this (compressedStream, mode, leaveOpen, false)
+               public DeflateStream (Stream stream, CompressionMode mode, bool leaveOpen) :
+                       this (stream, mode, leaveOpen, false)
                {
                }
 
@@ -124,23 +124,23 @@ namespace System.IO.Compression
                        }
                }
 
-               public override int Read (byte[] dest, int dest_offset, int count)
+               public override int Read (byte[] array, int offset, int count)
                {
                        if (disposed)
                                throw new ObjectDisposedException (GetType ().FullName);
-                       if (dest == null)
+                       if (array == null)
                                throw new ArgumentNullException ("Destination array is null.");
                        if (!CanRead)
                                throw new InvalidOperationException ("Stream does not support reading.");
-                       int len = dest.Length;
-                       if (dest_offset < 0 || count < 0)
+                       int len = array.Length;
+                       if (offset < 0 || count < 0)
                                throw new ArgumentException ("Dest or count is negative.");
-                       if (dest_offset > len)
+                       if (offset > len)
                                throw new ArgumentException ("destination offset is beyond array size");
-                       if ((dest_offset + count) > len)
+                       if ((offset + count) > len)
                                throw new ArgumentException ("Reading would overrun buffer");
 
-                       return ReadInternal (dest, dest_offset, count);
+                       return ReadInternal (array, offset, count);
                }
 
                unsafe void WriteInternal (byte[] array, int offset, int count)
@@ -154,16 +154,16 @@ namespace System.IO.Compression
                        }
                }
 
-               public override void Write (byte[] src, int src_offset, int count)
+               public override void Write (byte[] array, int offset, int count)
                {
                        if (disposed)
                                throw new ObjectDisposedException (GetType ().FullName);
 
-                       if (src == null)
-                               throw new ArgumentNullException ("src");
+                       if (array == null)
+                               throw new ArgumentNullException ("array");
 
-                       if (src_offset < 0)
-                               throw new ArgumentOutOfRangeException ("src_offset");
+                       if (offset < 0)
+                               throw new ArgumentOutOfRangeException ("offset");
 
                        if (count < 0)
                                throw new ArgumentOutOfRangeException ("count");
@@ -171,10 +171,10 @@ namespace System.IO.Compression
                        if (!CanWrite)
                                throw new NotSupportedException ("Stream does not support writing");
 
-                       if (src_offset > src.Length - count)
+                       if (offset > array.Length - count)
                                throw new ArgumentException ("Buffer too small. count/offset wrong.");
 
-                       WriteInternal (src, src_offset, count);
+                       WriteInternal (array, offset, count);
                }
 
                public override void Flush ()
index 88f774ad099edd5bf6a599438616d72972063f2b..edd8e93a893b77b53c1bdf9403113fe13edfa310 100644 (file)
@@ -70,21 +70,21 @@ namespace System.IO.Compression {
                        base.Dispose (disposing);
                }
 
-               public override int Read (byte[] dest, int dest_offset, int count)
+               public override int Read (byte[] array, int offset, int count)
                {
                        if (deflateStream == null)
                                throw new ObjectDisposedException (GetType ().FullName);
 
-                       return deflateStream.Read(dest, dest_offset, count);
+                       return deflateStream.Read(array, offset, count);
                }
 
 
-               public override void Write (byte[] src, int src_offset, int count)
+               public override void Write (byte[] array, int offset, int count)
                {
                        if (deflateStream == null)
                                throw new ObjectDisposedException (GetType ().FullName);
 
-                       deflateStream.Write (src, src_offset, count);
+                       deflateStream.Write (array, offset, count);
                }
 
                public override void Flush()
index 4bca32b7dccb027bbec28a44c2194f04b7ff0168..396b16f4c5416c06b77b6666e47c6404ea198e26 100644 (file)
@@ -230,6 +230,9 @@ namespace System.Net.Sockets
                                         * effects on Linux, as the socket option is kludged by
                                         * turning on or off PMTU discovery... */
                                        this.DontFragment = false;
+                                       this.NoDelay = false;
+                               } else if (address_family == AddressFamily.InterNetworkV6) {
+                                       this.DualMode = true;
                                }
 
                                /* Microsoft sets these to 8192, but we are going to keep them
@@ -811,7 +814,7 @@ namespace System.Net.Sockets
 
 #region Poll
 
-               public bool Poll (int time_us, SelectMode mode)
+               public bool Poll (int microSeconds, SelectMode mode)
                {
                        ThrowIfDisposedAndClosed ();
 
@@ -819,7 +822,7 @@ namespace System.Net.Sockets
                                throw new NotSupportedException ("'mode' parameter is not valid.");
 
                        int error;
-                       bool result = Poll_internal (safe_handle, mode, time_us, out error);
+                       bool result = Poll_internal (safe_handle, mode, microSeconds, out error);
 
                        if (error != 0)
                                throw new SocketException (error);
@@ -1115,27 +1118,27 @@ namespace System.Net.Sockets
 
 #region Bind
 
-               public void Bind (EndPoint local_end)
+               public void Bind (EndPoint localEP)
                {
                        ThrowIfDisposedAndClosed ();
 
-                       if (local_end == null)
-                               throw new ArgumentNullException("local_end");
+                       if (localEP == null)
+                               throw new ArgumentNullException("localEP");
                                
-                       var ipEndPoint = local_end as IPEndPoint;
+                       var ipEndPoint = localEP as IPEndPoint;
                        if (ipEndPoint != null) {
-                               local_end = RemapIPEndPoint (ipEndPoint);       
+                               localEP = RemapIPEndPoint (ipEndPoint); 
                        }
                        
                        int error;
-                       Bind_internal (safe_handle, local_end.Serialize(), out error);
+                       Bind_internal (safe_handle, localEP.Serialize(), out error);
 
                        if (error != 0)
                                throw new SocketException (error);
                        if (error == 0)
                                is_bound = true;
 
-                       seed_endpoint = local_end;
+                       seed_endpoint = localEP;
                }
 
                private static void Bind_internal (SafeSocketHandle safeHandle, SocketAddress sa, out int error)
@@ -1732,14 +1735,14 @@ namespace System.Net.Sockets
                        return Receive (buffer, SocketFlags.None);
                }
 
-               public int Receive (byte [] buffer, SocketFlags flags)
+               public int Receive (byte [] buffer, SocketFlags socketFlags)
                {
                        ThrowIfDisposedAndClosed ();
                        ThrowIfBufferNull (buffer);
                        ThrowIfBufferOutOfRange (buffer, 0, buffer.Length);
 
                        SocketError error;
-                       int ret = Receive_nochecks (buffer, 0, buffer.Length, flags, out error);
+                       int ret = Receive_nochecks (buffer, 0, buffer.Length, socketFlags, out error);
 
                        if (error != SocketError.Success) {
                                if (error == SocketError.WouldBlock && is_blocking) // This might happen when ReceiveTimeout is set
@@ -1750,14 +1753,14 @@ namespace System.Net.Sockets
                        return ret;
                }
 
-               public int Receive (byte [] buffer, int size, SocketFlags flags)
+               public int Receive (byte [] buffer, int size, SocketFlags socketFlags)
                {
                        ThrowIfDisposedAndClosed ();
                        ThrowIfBufferNull (buffer);
                        ThrowIfBufferOutOfRange (buffer, 0, size);
 
                        SocketError error;
-                       int ret = Receive_nochecks (buffer, 0, size, flags, out error);
+                       int ret = Receive_nochecks (buffer, 0, size, socketFlags, out error);
 
                        if (error != SocketError.Success) {
                                if (error == SocketError.WouldBlock && is_blocking) // This might happen when ReceiveTimeout is set
@@ -1768,14 +1771,14 @@ namespace System.Net.Sockets
                        return ret;
                }
 
-               public int Receive (byte [] buffer, int offset, int size, SocketFlags flags)
+               public int Receive (byte [] buffer, int offset, int size, SocketFlags socketFlags)
                {
                        ThrowIfDisposedAndClosed ();
                        ThrowIfBufferNull (buffer);
                        ThrowIfBufferOutOfRange (buffer, offset, size);
 
                        SocketError error;
-                       int ret = Receive_nochecks (buffer, offset, size, flags, out error);
+                       int ret = Receive_nochecks (buffer, offset, size, socketFlags, out error);
 
                        if (error != SocketError.Success) {
                                if (error == SocketError.WouldBlock && is_blocking) // This might happen when ReceiveTimeout is set
@@ -1786,13 +1789,13 @@ namespace System.Net.Sockets
                        return ret;
                }
 
-               public int Receive (byte [] buffer, int offset, int size, SocketFlags flags, out SocketError error)
+               public int Receive (byte [] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode)
                {
                        ThrowIfDisposedAndClosed ();
                        ThrowIfBufferNull (buffer);
                        ThrowIfBufferOutOfRange (buffer, offset, size);
 
-                       return Receive_nochecks (buffer, offset, size, flags, out error);
+                       return Receive_nochecks (buffer, offset, size, socketFlags, out errorCode);
                }
 
                public int Receive (IList<ArraySegment<byte>> buffers)
@@ -2075,24 +2078,24 @@ namespace System.Net.Sockets
                        return ReceiveFrom (buffer, 0, buffer.Length, SocketFlags.None, ref remoteEP);
                }
 
-               public int ReceiveFrom (byte [] buffer, SocketFlags flags, ref EndPoint remoteEP)
+               public int ReceiveFrom (byte [] buffer, SocketFlags socketFlags, ref EndPoint remoteEP)
                {
                        ThrowIfDisposedAndClosed ();
                        ThrowIfBufferNull (buffer);
 
-                       return ReceiveFrom (buffer, 0, buffer.Length, flags, ref remoteEP);
+                       return ReceiveFrom (buffer, 0, buffer.Length, socketFlags, ref remoteEP);
                }
 
-               public int ReceiveFrom (byte [] buffer, int size, SocketFlags flags, ref EndPoint remoteEP)
+               public int ReceiveFrom (byte [] buffer, int size, SocketFlags socketFlags, ref EndPoint remoteEP)
                {
                        ThrowIfDisposedAndClosed ();
                        ThrowIfBufferNull (buffer);
                        ThrowIfBufferOutOfRange (buffer, 0, size);
 
-                       return ReceiveFrom (buffer, 0, size, flags, ref remoteEP);
+                       return ReceiveFrom (buffer, 0, size, socketFlags, ref remoteEP);
                }
 
-               public int ReceiveFrom (byte [] buffer, int offset, int size, SocketFlags flags, ref EndPoint remoteEP)
+               public int ReceiveFrom (byte [] buffer, int offset, int size, SocketFlags socketFlags, ref EndPoint remoteEP)
                {
                        ThrowIfDisposedAndClosed ();
                        ThrowIfBufferNull (buffer);
@@ -2102,7 +2105,7 @@ namespace System.Net.Sockets
                                throw new ArgumentNullException ("remoteEP");
 
                        int error;
-                       return ReceiveFrom_nochecks_exc (buffer, offset, size, flags, ref remoteEP, true, out error);
+                       return ReceiveFrom_nochecks_exc (buffer, offset, size, socketFlags, ref remoteEP, true, out error);
                }
 
                public bool ReceiveFromAsync (SocketAsyncEventArgs e)
@@ -2325,14 +2328,14 @@ namespace System.Net.Sockets
                        return ret;
                }
 
-               public int Send (byte [] buffer, SocketFlags flags)
+               public int Send (byte [] buffer, SocketFlags socketFlags)
                {
                        ThrowIfDisposedAndClosed ();
                        ThrowIfBufferNull (buffer);
                        ThrowIfBufferOutOfRange (buffer, 0, buffer.Length);
 
                        SocketError error;
-                       int ret = Send_nochecks (buffer, 0, buffer.Length, flags, out error);
+                       int ret = Send_nochecks (buffer, 0, buffer.Length, socketFlags, out error);
 
                        if (error != SocketError.Success)
                                throw new SocketException ((int) error);
@@ -2340,14 +2343,14 @@ namespace System.Net.Sockets
                        return ret;
                }
 
-               public int Send (byte [] buffer, int size, SocketFlags flags)
+               public int Send (byte [] buffer, int size, SocketFlags socketFlags)
                {
                        ThrowIfDisposedAndClosed ();
                        ThrowIfBufferNull (buffer);
                        ThrowIfBufferOutOfRange (buffer, 0, size);
 
                        SocketError error;
-                       int ret = Send_nochecks (buffer, 0, size, flags, out error);
+                       int ret = Send_nochecks (buffer, 0, size, socketFlags, out error);
 
                        if (error != SocketError.Success)
                                throw new SocketException ((int) error);
@@ -2355,14 +2358,14 @@ namespace System.Net.Sockets
                        return ret;
                }
 
-               public int Send (byte [] buffer, int offset, int size, SocketFlags flags)
+               public int Send (byte [] buffer, int offset, int size, SocketFlags socketFlags)
                {
                        ThrowIfDisposedAndClosed ();
                        ThrowIfBufferNull (buffer);
                        ThrowIfBufferOutOfRange (buffer, offset, size);
 
                        SocketError error;
-                       int ret = Send_nochecks (buffer, offset, size, flags, out error);
+                       int ret = Send_nochecks (buffer, offset, size, socketFlags, out error);
 
                        if (error != SocketError.Success)
                                throw new SocketException ((int) error);
@@ -2370,13 +2373,13 @@ namespace System.Net.Sockets
                        return ret;
                }
 
-               public int Send (byte [] buffer, int offset, int size, SocketFlags flags, out SocketError error)
+               public int Send (byte [] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode)
                {
                        ThrowIfDisposedAndClosed ();
                        ThrowIfBufferNull (buffer);
                        ThrowIfBufferOutOfRange (buffer, offset, size);
 
-                       return Send_nochecks (buffer, offset, size, flags, out error);
+                       return Send_nochecks (buffer, offset, size, socketFlags, out errorCode);
                }
 
                public
@@ -2685,37 +2688,37 @@ namespace System.Net.Sockets
 
 #region SendTo
 
-               public int SendTo (byte [] buffer, EndPoint remote_end)
+               public int SendTo (byte [] buffer, EndPoint remoteEP)
                {
                        ThrowIfDisposedAndClosed ();
                        ThrowIfBufferNull (buffer);
 
-                       return SendTo (buffer, 0, buffer.Length, SocketFlags.None, remote_end);
+                       return SendTo (buffer, 0, buffer.Length, SocketFlags.None, remoteEP);
                }
 
-               public int SendTo (byte [] buffer, SocketFlags flags, EndPoint remote_end)
+               public int SendTo (byte [] buffer, SocketFlags socketFlags, EndPoint remoteEP)
                {
                        ThrowIfDisposedAndClosed ();
                        ThrowIfBufferNull (buffer);
 
-                       return SendTo (buffer, 0, buffer.Length, flags, remote_end);
+                       return SendTo (buffer, 0, buffer.Length, socketFlags, remoteEP);
                }
 
-               public int SendTo (byte [] buffer, int size, SocketFlags flags, EndPoint remote_end)
+               public int SendTo (byte [] buffer, int size, SocketFlags socketFlags, EndPoint remoteEP)
                {
-                       return SendTo (buffer, 0, size, flags, remote_end);
+                       return SendTo (buffer, 0, size, socketFlags, remoteEP);
                }
 
-               public int SendTo (byte [] buffer, int offset, int size, SocketFlags flags, EndPoint remote_end)
+               public int SendTo (byte [] buffer, int offset, int size, SocketFlags socketFlags, EndPoint remoteEP)
                {
                        ThrowIfDisposedAndClosed ();
                        ThrowIfBufferNull (buffer);
                        ThrowIfBufferOutOfRange (buffer, offset, size);
 
-                       if (remote_end == null)
-                               throw new ArgumentNullException("remote_end");
+                       if (remoteEP == null)
+                               throw new ArgumentNullException("remoteEP");
 
-                       return SendTo_nochecks (buffer, offset, size, flags, remote_end);
+                       return SendTo_nochecks (buffer, offset, size, socketFlags, remoteEP);
                }
 
                public bool SendToAsync (SocketAsyncEventArgs e)
@@ -3027,12 +3030,12 @@ namespace System.Net.Sockets
                                throw new SocketException (error);
                }
 
-               public byte [] GetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, int length)
+               public byte [] GetSocketOption (SocketOptionLevel optionLevel, SocketOptionName optionName, int optionLength)
                {
                        ThrowIfDisposedAndClosed ();
 
                        int error;
-                       byte[] byte_val = new byte [length];
+                       byte[] byte_val = new byte [optionLength];
                        GetSocketOption_arr_internal (safe_handle, optionLevel, optionName, ref byte_val, out error);
 
                        if (error != 0)
@@ -3193,13 +3196,13 @@ namespace System.Net.Sockets
 
 #region IOControl
 
-               public int IOControl (int ioctl_code, byte [] in_value, byte [] out_value)
+               public int IOControl (int ioControlCode, byte [] optionInValue, byte [] optionOutValue)
                {
                        if (is_disposed)
                                throw new ObjectDisposedException (GetType ().ToString ());
 
                        int error;
-                       int result = IOControl_internal (safe_handle, ioctl_code, in_value, out_value, out error);
+                       int result = IOControl_internal (safe_handle, ioControlCode, optionInValue, optionOutValue, out error);
 
                        if (error != 0)
                                throw new SocketException (error);
index 25a5d2877fdc4e4d6409f3c4d8a14b26469593e6..9f94783258dfa6a4067bebd666584507334cfd6c 100644 (file)
@@ -450,7 +450,7 @@ namespace System.Net
                                        newWebHeaders.Add(headerName,webHeaders[headerName]);
                                }
 
-                               webHeaders = newWebHeaders;
+                               this.webHeaders = newWebHeaders;
                        }
                }
                
index 97b7b1c70c78e41f3e330d57ccee2a304d288278..c9754ea29997238d897cbc86e023eda7b1852677 100644 (file)
@@ -34,16 +34,16 @@ namespace System.Security.AccessControl {
        public sealed class SemaphoreAccessRule : AccessRule
        {
                public SemaphoreAccessRule (IdentityReference identity,
-                                           SemaphoreRights semaphoreRights,
+                                           SemaphoreRights eventRights,
                                            AccessControlType type)
-                       : base (identity, (int)semaphoreRights, false, InheritanceFlags.None, PropagationFlags.None, type)
+                       : base (identity, (int)eventRights, false, InheritanceFlags.None, PropagationFlags.None, type)
                {
                }
 
                public SemaphoreAccessRule (string identity,
-                                           SemaphoreRights semaphoreRights,
+                                           SemaphoreRights eventRights,
                                            AccessControlType type)
-                       : this (new NTAccount (identity), semaphoreRights, type)
+                       : this (new NTAccount (identity), eventRights, type)
                {
                }
                
index 5680f0f7ed812f36303b1a560f9266acdda8ec09..acc495ce45d1508752dcdf4a1700a2c322c40131 100644 (file)
@@ -35,9 +35,9 @@ namespace System.Security.AccessControl {
                : AuditRule
        {
                public SemaphoreAuditRule (IdentityReference identity,
-                                          SemaphoreRights semaphoreRights,
+                                          SemaphoreRights eventRights,
                                           AuditFlags flags)
-                       : base (identity, (int)semaphoreRights, false, InheritanceFlags.None, PropagationFlags.None, flags)
+                       : base (identity, (int)eventRights, false, InheritanceFlags.None, PropagationFlags.None, flags)
                {
                }
                
index 15de9f7b3cce674e63d8f7dd3a41c22ae2bbe0a0..192c9bd4d7516a27092e22ed6959429e07f826aa 100644 (file)
@@ -94,14 +94,14 @@ namespace System.Security.Cryptography.X509Certificates {
 
                // methods
 
-               public override void CopyFrom (AsnEncodedData encodedData)
+               public override void CopyFrom (AsnEncodedData asnEncodedData)
                {
-                       if (encodedData == null)
-                               throw new ArgumentNullException ("encodedData");
+                       if (asnEncodedData == null)
+                               throw new ArgumentNullException ("asnEncodedData");
 
-                       X509Extension ex = (encodedData as X509Extension);
+                       X509Extension ex = (asnEncodedData as X509Extension);
                        if (ex == null)
-                               throw new ArgumentException (Locale.GetText ("Wrong type."), "encodedData");
+                               throw new ArgumentException (Locale.GetText ("Wrong type."), "asnEncodedData");
 
                        if (ex._oid == null)
                                _oid = new Oid (oid, friendlyName);
index 89e7afb963c119867ef2340516653ac879ac7855..bf24e85f8c6ce674e451b0680a5ea6fc56b294d1 100644 (file)
@@ -159,14 +159,14 @@ namespace System.Security.Cryptography.X509Certificates {
 
                // methods
 
-               public override void CopyFrom (AsnEncodedData encodedData)
+               public override void CopyFrom (AsnEncodedData asnEncodedData)
                {
-                       if (encodedData == null)
-                               throw new ArgumentNullException ("encodedData");
+                       if (asnEncodedData == null)
+                               throw new ArgumentNullException ("asnEncodedData");
 
-                       X509Extension ex = (encodedData as X509Extension);
+                       X509Extension ex = (asnEncodedData as X509Extension);
                        if (ex == null)
-                               throw new ArgumentException (Locale.GetText ("Wrong type."), "encodedData");
+                               throw new ArgumentException (Locale.GetText ("Wrong type."), "asnEncodedData");
 
                        if (ex._oid == null)
                                _oid = new Oid (oid, friendlyName);
index 2ae31073e578abcc8593f01c833c7911ee7a5b2e..0fe01aaf102cd2c04b499ef4f1822e4da01a6955 100644 (file)
@@ -343,7 +343,6 @@ namespace MonoTests.System.IO.Compression
                        return new MemoryStream (Encoding.UTF8.GetBytes (s));
                }
 
-#if NET_4_5
                [Test]
                public void CheckNet45Overloads () // Xambug #21982
                {
@@ -361,7 +360,6 @@ namespace MonoTests.System.IO.Compression
                        decompressing.Close();
                        backing.Close();
                }
-#endif 
 
                [Test]
                [ExpectedException (typeof (ArgumentException))]
index a72ffc6ee05be349d7ef0ef6a5e06e2dfe08a483..47a740ca14ace19a3450a045a7720c6cabe83cf7 100644 (file)
@@ -303,7 +303,6 @@ namespace MonoTests.System.IO.Compression
                        return new MemoryStream (Encoding.UTF8.GetBytes (s));
                }
 
-#if NET_4_5
                [Test]
                public void CheckNet45Overloads () // Xambug #21982
                {
@@ -321,7 +320,6 @@ namespace MonoTests.System.IO.Compression
                        decompressing.Close();
                        backing.Close();
                }
-#endif
        }
 }
 
index 9551c1e6027131d4217bd59a13d986438873d5e2..4955d3f3c6096effcfa6a54a0c6dfb2a53b937e7 100755 (executable)
@@ -1207,9 +1207,9 @@ namespace MonoTests.System.Net.Sockets
                        Socket sock = new Socket (AddressFamily.InterNetwork,
                                                  SocketType.Stream,
                                                  ProtocolType.Tcp);
-                       
+
                        Assert.AreEqual (false, sock.NoDelay, "NoDelayDefaultTcp");
-                       
+
                        sock.Close ();
                }
 
@@ -4287,51 +4287,84 @@ namespace MonoTests.System.Net.Sockets
                
                [Test]
                public void ConnectToIPV4EndPointUsingDualModelSocket () {
-                       using (var server = new Socket (SocketType.Stream, ProtocolType.Tcp))
-                       using (var client = new Socket (SocketType.Stream, ProtocolType.Tcp)) {
+                       /*
+                        * IPv6 DualMode sockets are defaults in Mono. Explicitly specify that
+                        * anyways in this test to make it more interoparable with .NET where
+                        * IPv6 and DualMode needs to be specified.
+                        */
+                       using (var server = new Socket (AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp)) {
+
                                var host = new IPEndPoint (IPAddress.Loopback, NetworkHelpers.FindFreePort ());
-                                       
+
+                               server.DualMode = true;
                                server.Bind (host);
-                               server.Listen (0);
+                               /*
+                                * Nothing to Accept the connect - we need a backlog to make sure we don't get 
+                                Connection refused.
+                                */
+                               server.Listen (3);
                                
                                var ep = server.LocalEndPoint as IPEndPoint;
-                               
+                               var client = new Socket (AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
+                               client.DualMode = true;
                                client.Connect (ep);
-                               client.Disconnect (true);
-                               
+                               client.Disconnect (false);
+                               client.Close ();
+
+                               client = new Socket (AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
+                               client.DualMode = true;
                                client.Connect (IPAddress.Loopback, ep.Port);
-                               client.Disconnect (true);
-                               
-                               client.Connect (new [] {IPAddress.Loopback}, ep.Port);
-                               client.Disconnect (true);
+                               client.Disconnect (false);
+                               client.Close ();
+
+                               client = new Socket (AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
+                               client.DualMode = true;
+                               client.Connect (new [] { IPAddress.Loopback }, ep.Port);
+                               client.Disconnect (false);
+                               client.Close ();
                        }
                }
                
                [Test]
                public void BeginConnectToIPV4EndPointUsingDualModelSocket () {
-                       using (var server = new Socket (SocketType.Stream, ProtocolType.Tcp))
-                       using (var client = new Socket (SocketType.Stream, ProtocolType.Tcp)) {
+                       /*
+                        * IPv6 DualMode sockets are defaults in Mono. Explicitly specify that
+                        * anyways in this test to make it more interoparable with .NET where
+                        * IPv6 and DualMode needs to be specified.
+                        */
+                       using (var server = new Socket (AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp))
+                       {
                                var host = new IPEndPoint (IPAddress.Loopback, NetworkHelpers.FindFreePort ());
-                                       
+
+                               server.DualMode = true;
                                server.Bind (host);
-                               server.Listen (0);
+                               server.Listen (10);
                                
                                var ep = server.LocalEndPoint as IPEndPoint;
-                               
+
                                BCCalledBack.Reset ();
+                               var client = new Socket (AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
+                               client.DualMode = true;
                                var ar1 = client.BeginConnect (ep, BCCallback, client);
                                Assert.IsTrue (BCCalledBack.WaitOne (10000), "#1");
-                               client.Disconnect (true);
-                               
+                               client.Disconnect (false);
+                               client.Close ();
+
                                BCCalledBack.Reset ();
+                               client = new Socket (AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
+                               client.DualMode = true;
                                var ar2 = client.BeginConnect (IPAddress.Loopback, ep.Port, BCCallback, client);
                                Assert.IsTrue (BCCalledBack.WaitOne (10000), "#2");
-                               client.Disconnect (true);
-                               
+                               client.Disconnect (false);
+                               client.Close ();
+
                                BCCalledBack.Reset ();
+                               client = new Socket (AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
+                               client.DualMode = true;
                                var ar3 = client.BeginConnect (new [] {IPAddress.Loopback}, ep.Port, BCCallback, client);
                                Assert.IsTrue (BCCalledBack.WaitOne (10000), "#2");
-                               client.Disconnect (true);
+                               client.Disconnect (false);
+                               client.Close();
                        }
                }
 
index 0638cb720b3a57d67b0879d93f72fce0a3bda685..4e7aa5668c35bc304532a5f6e14a716d069f1e72 100644 (file)
@@ -1,4 +1,3 @@
-#if NET_4_5
 using System;
 using System.Net;
 using System.Threading;
@@ -297,4 +296,3 @@ namespace MonoTests.System.Net.WebSockets
        }
 }
 
-#endif
index b7097b5db56a7e930149f96f641b3df8997559a1..0d5763967b0d01256f3504a608fc899dfa65941e 100644 (file)
@@ -2482,7 +2482,6 @@ namespace MonoTests.System.Net
                        }
                }
 
-#if NET_4_5
                [Test]
                public void AllowReadStreamBuffering ()
                {
@@ -2494,7 +2493,6 @@ namespace MonoTests.System.Net
                        } catch (InvalidOperationException) {
                        }
                }
-#endif
 
                class ListenerScope : IDisposable {
                        EventWaitHandle completed;
index 9eb5877052ea3430303a703c1219ad5f73f81d1e..1a6c45179aa8f65d7fb4e63909010ca984332d54 100644 (file)
@@ -1781,7 +1781,6 @@ namespace MonoTests.System.Net
                        Assert.AreSame (wc.Proxy, WebRequest.DefaultWebProxy);
                }
                 
-#if NET_4_5
                [Test]
                [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
                public void UploadStringAsyncCancelEvent ()
@@ -1873,7 +1872,6 @@ namespace MonoTests.System.Net
                        }
                        listener.Close ();
                }
-#endif
 
                public void UploadAsyncCancelEventTest (int port, Action<WebClient, Uri, EventWaitHandle> uploadAction)
                {
index aabaceb9f4a73cd4ce970c74d02e27f938686035..0b404581899f7cdd81bb2421c0ac1f5e537a022d 100644 (file)
@@ -26,7 +26,6 @@
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
-#if NET_4_5
 using System;
 using System.IO;
 using System.Collections.Generic;
@@ -276,4 +275,3 @@ namespace MonoTests.System.Net
                }
        }
 }
-#endif
index 7d9d24052f3c985d4df6f82244ac578051a3e92b..308c3bdf39a36e865b54fcf35ee2ad3ab3ae9340 100644 (file)
@@ -62,11 +62,7 @@ namespace MonoTests.System {
                public void Setup()
                {
                        StringTester.CreateMode = createMode;
-#if NET_4_5
                        StringTester.Location = location + "NET_4_5";
-#else
-                       StringTester.Location = location + "NET_4_0";
-#endif
                }
 
                [TearDown]
index 32c3fb0459e10829d7a0b9419f3eb99dfc72cd72..6ebd708ee02c0ea845f317e30f6d1f58230f7a20 100644 (file)
@@ -836,11 +836,7 @@ namespace MonoTests.System
                {
                        Uri u = new Uri("http://localhost/index.asp#main#start", false);
 
-#if NET_4_5
                                Assert.AreEqual (u.Fragment, "#main#start", "#1");
-#else
-                               Assert.AreEqual (u.Fragment, "#main%23start", "#1");
-#endif
 
                        u = new Uri("http://localhost/index.asp#main#start", true);
                        Assert.AreEqual (u.Fragment, "#main#start", "#2");
@@ -849,11 +845,7 @@ namespace MonoTests.System
 
                        Uri b = new Uri ("http://www.gnome.org");
                        Uri n = new Uri (b, "blah#main#start");
-#if NET_4_5
                                Assert.AreEqual (n.Fragment, "#main#start", "#3");
-#else
-                               Assert.AreEqual (n.Fragment, "#main%23start", "#3");
-#endif
 
                        n = new Uri (b, "blah#main#start", true);
                        Assert.AreEqual (n.Fragment, "#main#start", "#4");
@@ -1071,13 +1063,8 @@ namespace MonoTests.System
                        Uri ftp = new Uri ("FTP://[::ffFF:169.32.14.5]/");
                        Assert.AreEqual ("ftp", ftp.Scheme, "#7");
 
-#if NET_4_5
                        Assert.AreEqual ("[::ffff:169.32.14.5]", ftp.Host, "#8");
                        Assert.AreEqual ("ftp://[::ffff:169.32.14.5]/", ftp.ToString (), "#9");
-#else
-                       Assert.AreEqual ("[0000:0000:0000:0000:0000:FFFF:A920:0E05]", ftp.Host, "#8");
-                       Assert.AreEqual ("ftp://[0000:0000:0000:0000:0000:FFFF:A920:0E05]/", ftp.ToString (), "#9");
-#endif
                }
 
                [Test]
@@ -1484,15 +1471,9 @@ namespace MonoTests.System
                        for (int i = 0; i < 128; i++)
                                sb.Append ((char) i);
 
-#if NET_4_5
                        Assert.AreEqual (
                                "%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~%7F",
                                Uri.EscapeDataString (sb.ToString ()));
-#else
-                       Assert.AreEqual (
-                               "%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20!%22%23%24%25%26'()*%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~%7F",
-                               Uri.EscapeDataString (sb.ToString ()));
-#endif
 
                        Assert.AreEqual ("%C3%A1", Uri.EscapeDataString ("á"));
                }
@@ -1503,15 +1484,9 @@ namespace MonoTests.System
                        for (int i = 0; i < 128; i++)
                                sb.Append ((char) i);
 
-#if NET_4_5
                        Assert.AreEqual (
                                "%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20!%22#$%25&'()*+,-./0123456789:;%3C=%3E?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[%5C]%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~%7F",
                                Uri.EscapeUriString (sb.ToString ()));
-#else
-                       Assert.AreEqual (
-                               "%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20!%22#$%25&'()*+,-./0123456789:;%3C=%3E?@ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~%7F",
-                               Uri.EscapeUriString (sb.ToString ()));
-#endif
 
                        Assert.AreEqual ("%C3%A1", Uri.EscapeDataString ("á"));
                }
index 5b27b8aaf90cf7a371b61a6961e77b1f2d5d3a28..220967e09e4b157c1bd72f731002968cff817139 100644 (file)
@@ -241,48 +241,66 @@ namespace Microsoft.Win32
                public void SetValue (RegistryKey rkey, string name, object value, RegistryValueKind valueKind)
                {
                        Type type = value.GetType ();
-                       int result;
                        IntPtr handle = GetHandle (rkey);
 
-                       if (valueKind == RegistryValueKind.QWord && type == typeof (long)) {
-                               long rawValue = (long)value;
-                               result = RegSetValueEx (handle, name, IntPtr.Zero, RegistryValueKind.QWord, ref rawValue, Int64ByteSize); 
-                       } else if (valueKind == RegistryValueKind.DWord && type == typeof (int)) {
-                               int rawValue = (int)value;
-                               result = RegSetValueEx (handle, name, IntPtr.Zero, RegistryValueKind.DWord, ref rawValue, Int32ByteSize); 
-                       } else if (valueKind == RegistryValueKind.Binary && type == typeof (byte[])) {
-                               byte[] rawValue = (byte[]) value;
-                               result = RegSetValueEx (handle, name, IntPtr.Zero, RegistryValueKind.Binary, rawValue, rawValue.Length);
-                       } else if (valueKind == RegistryValueKind.MultiString && type == typeof (string[])) {
-                               string[] vals = (string[]) value;
-                               StringBuilder fullStringValue = new StringBuilder ();
-                               foreach (string v in vals)
-                               {
-                                       fullStringValue.Append (v);
-                                       fullStringValue.Append ('\0');
+                       switch (valueKind) {
+                       case RegistryValueKind.QWord:
+                               try {
+                                       long rawValue = Convert.ToInt64 (value);
+                                       CheckResult (RegSetValueEx (handle, name, IntPtr.Zero, RegistryValueKind.QWord, ref rawValue, Int64ByteSize));
+                                       return;
+                               } catch (OverflowException) {
                                }
-                               fullStringValue.Append ('\0');
+                               break;
+                       case RegistryValueKind.DWord:
+                               try {
+                                       int rawValue = Convert.ToInt32 (value);
+                                       CheckResult (RegSetValueEx (handle, name, IntPtr.Zero, RegistryValueKind.DWord, ref rawValue, Int32ByteSize));
+                                       return;
+                               } catch (OverflowException) {
+                               }
+                               break;
+                       case RegistryValueKind.Binary:
+                               if (type == typeof (byte[])) {
+                                       byte[] rawValue = (byte[]) value;
+                                       CheckResult (RegSetValueEx (handle, name, IntPtr.Zero, RegistryValueKind.Binary, rawValue, rawValue.Length));
+                                       return;
+                               }
+                               break;
+                       case RegistryValueKind.MultiString:
+                               if (type == typeof (string[])) {
+                                       string[] vals = (string[]) value;
+                                       StringBuilder fullStringValue = new StringBuilder ();
+                                       foreach (string v in vals)
+                                       {
+                                               fullStringValue.Append (v);
+                                               fullStringValue.Append ('\0');
+                                       }
+                                       fullStringValue.Append ('\0');
 
-                               byte[] rawValue = Encoding.Unicode.GetBytes (fullStringValue.ToString ());
+                                       byte[] rawValue = Encoding.Unicode.GetBytes (fullStringValue.ToString ());
                        
-                               result = RegSetValueEx (handle, name, IntPtr.Zero, RegistryValueKind.MultiString, rawValue, rawValue.Length); 
-                       } else if ((valueKind == RegistryValueKind.String || valueKind == RegistryValueKind.ExpandString) &&
-                                  type == typeof (string)){
-                               string rawValue = String.Format ("{0}{1}", value, '\0');
-                               result = RegSetValueEx (handle, name, IntPtr.Zero, valueKind, rawValue,
-                                                       rawValue.Length * NativeBytesPerCharacter);
-                               
-                       } else if (type.IsArray) {
-                               throw new ArgumentException ("Only string and byte arrays can written as registry values");
-                       } else {
-                               throw new ArgumentException ("Type does not match the valueKind");
+                                       CheckResult (RegSetValueEx (handle, name, IntPtr.Zero, RegistryValueKind.MultiString, rawValue, rawValue.Length));
+                                       return;
+                               }
+                               break;
+                       case RegistryValueKind.String:
+                       case RegistryValueKind.ExpandString:
+                               if (type == typeof (string)) {
+                                       string rawValue = String.Format ("{0}{1}", value, '\0');
+                                       CheckResult (RegSetValueEx (handle, name, IntPtr.Zero, valueKind, rawValue,
+                                                               rawValue.Length * NativeBytesPerCharacter));
+                                       return;
+                               }
+                               break;
+                       default:
+                               if (type.IsArray) {
+                                       throw new ArgumentException ("Only string and byte arrays can written as registry values");
+                               }
+                               break;
                        }
 
-                       // handle the result codes
-                       if (result != Win32ResultCode.Success)
-                       {
-                               GenerateException (result);
-                       }
+                       throw new ArgumentException ("Type does not match the valueKind");
                }
        
                public void SetValue (RegistryKey rkey, string name, object value)
@@ -318,9 +336,6 @@ namespace Microsoft.Win32
                                                        rawValue.Length * NativeBytesPerCharacter);
                        }
 
-                       if (result == Win32ResultCode.MarkedForDeletion)
-                               throw RegistryKey.CreateMarkedForDeletionException ();
-
                        // handle the result codes
                        if (result != Win32ResultCode.Success)
                        {
@@ -356,9 +371,6 @@ namespace Microsoft.Win32
                                int result = RegEnumKey (handle, index, stringBuffer,
                                        stringBuffer.Capacity);
 
-                               if (result == Win32ResultCode.MarkedForDeletion)
-                                       throw RegistryKey.CreateMarkedForDeletionException ();
-
                                if (result == Win32ResultCode.Success)
                                        continue;
                                
@@ -386,9 +398,6 @@ namespace Microsoft.Win32
                                                       IntPtr.Zero, ref type, 
                                                       IntPtr.Zero, IntPtr.Zero);
 
-                               if (result == Win32ResultCode.MarkedForDeletion)
-                                       throw RegistryKey.CreateMarkedForDeletionException ();
-
                                if (result == Win32ResultCode.Success || result == Win32ResultCode.MoreData)
                                        continue;
                                
@@ -470,9 +479,6 @@ namespace Microsoft.Win32
                                RegOptionsNonVolatile,
                                OpenRegKeyRead | OpenRegKeyWrite, IntPtr.Zero, out subKeyHandle, out disposition);
 
-                       if (result == Win32ResultCode.MarkedForDeletion)
-                               throw RegistryKey.CreateMarkedForDeletionException ();
-
                        if (result != Win32ResultCode.Success) {
                                GenerateException (result);
                        }
@@ -490,9 +496,6 @@ namespace Microsoft.Win32
                                options == RegistryOptions.Volatile ? RegOptionsVolatile : RegOptionsNonVolatile,
                                OpenRegKeyRead | OpenRegKeyWrite, IntPtr.Zero, out subKeyHandle, out disposition);
 
-                       if (result == Win32ResultCode.MarkedForDeletion)
-                               throw RegistryKey.CreateMarkedForDeletionException ();
-
                        if (result != Win32ResultCode.Success)
                                GenerateException (result);
                        
@@ -580,15 +583,19 @@ namespace Microsoft.Win32
                                if (result == Win32ResultCode.NoMoreEntries)
                                        break;
 
-                               if (result == Win32ResultCode.MarkedForDeletion)
-                                       throw RegistryKey.CreateMarkedForDeletionException ();
-
                                GenerateException (result);
                        }
 
                        return values.ToArray ();
                }
 
+               private void CheckResult (int result)
+               {
+                       if (result != Win32ResultCode.Success) {
+                               GenerateException (result);
+                       }
+               }
+
                /// <summary>
                /// convert a win32 error code into an appropriate exception.
                /// </summary>
@@ -604,6 +611,10 @@ namespace Microsoft.Win32
                                        throw new IOException ("The network path was not found.");
                                case Win32ResultCode.InvalidHandle:
                                        throw new IOException ("Invalid handle.");
+                               case Win32ResultCode.MarkedForDeletion:
+                                       throw RegistryKey.CreateMarkedForDeletionException ();
+                               case Win32ResultCode.ChildMustBeVolatile:
+                                       throw new IOException ("Cannot create a stable subkey under a volatile parent key.");
                                default:
                                        // unidentified system exception
                                        throw new SystemException ();
index ba69eb7d5a453234476e8db68ff98145aa8be453..4e8e85d0e85e8e77c050218454b158f705730613 100644 (file)
@@ -58,6 +58,7 @@ namespace Microsoft.Win32
                public const int NetworkPathNotFound = 53;
                public const int NoMoreEntries = 259;
                public const int MarkedForDeletion = 1018;
+               public const int ChildMustBeVolatile = 1021;
        }
 }
 
index 104516c3e934b25c896330bf7df3f381d7eaafca..9be2deb9e2e84f2db87abe40b6968dd4eaf685d3 100644 (file)
@@ -1015,7 +1015,7 @@ namespace Mono.Security {
                        }
                        
                        // 5 path
-                       pos = uriString.IndexOfAny (new char[] {'/'});
+                       pos = uriString.IndexOfAny (new char[] {'/', '\\'});
                        if (unixAbsPath)
                                pos = -1;
                        if (pos == -1) {
@@ -1042,6 +1042,8 @@ namespace Mono.Security {
                        pos = uriString.LastIndexOf (":");
                        if (unixAbsPath)
                                pos = -1;
+                       if (pos == 1 && scheme == Uri.UriSchemeFile && Char.IsLetter (uriString [0]))
+                               pos = -1;
                        if (pos != -1 && pos != (uriString.Length - 1)) {
                                string portStr = uriString.Remove (0, pos + 1);
                                if (portStr.Length > 1 && portStr [portStr.Length - 1] != ']') {
index 6225954fb7011b60ec882c966f4199b7a9021874..f70ee556ac6adb177de9fa5cc15cc469928fefca 100644 (file)
@@ -12,6 +12,8 @@
 using System;
 using System.Runtime.InteropServices;
 
+#pragma warning disable 169
+
 namespace Mono {
        //
        // Managed representations of mono runtime types
index 55d45d833e3f6a5c74d371e8e118d0e5861f7edd..8874423d8492c49421debe9a2795fd721964f6a8 100644 (file)
@@ -2,5 +2,6 @@ namespace System {
        static class AppContextSwitches {
                public static readonly bool ThrowExceptionIfDisposedCancellationTokenSource = true;
                public static readonly bool SetActorAsReferenceWhenCopyingClaimsIdentity = false;
+               public static readonly bool NoAsyncCurrentCulture = false;
        }
 }
\ No newline at end of file
index ccf9f835734b97315cba343aebb816fa5fbb89f4..b93808b89c4f6afa045a3f412642b90853dbb0e1 100644 (file)
@@ -251,7 +251,7 @@ namespace System.Diagnostics {
                        return i != 0;
                }
 
-               public static void GetFullNameForStackTrace (StringBuilder sb, MethodBase mi)
+               internal void GetFullNameForStackTrace (StringBuilder sb, MethodBase mi)
                {
                        var declaringType = mi.DeclaringType;
                        if (declaringType.IsGenericType && !declaringType.IsGenericTypeDefinition)
index 7d043f2300c6d6a50f866eea25fd83b3c10084d9..e6741d4d3caf2c0cf6467e382e9821c4281646eb 100644 (file)
@@ -116,6 +116,9 @@ namespace System.Globalization
                const int CalendarTypeBits = 8;
 
                const string MSG_READONLY = "This instance is read only";
+
+               static volatile CultureInfo s_DefaultThreadCurrentUICulture;
+               static volatile CultureInfo s_DefaultThreadCurrentCulture;
                
                public static CultureInfo InvariantCulture {
                        get {
@@ -127,22 +130,18 @@ namespace System.Globalization
                        get {
                                return Thread.CurrentThread.CurrentCulture;
                        }
-#if NETSTANDARD
                        set {
-                               throw new NotImplementedException ();
+                               Thread.CurrentThread.CurrentCulture = value;
                        }
-#endif
                }
 
                public static CultureInfo CurrentUICulture { 
                        get {
                                return Thread.CurrentThread.CurrentUICulture;
                        }
-#if NETSTANDARD
                        set {
-                               throw new NotImplementedException ();
+                               Thread.CurrentThread.CurrentUICulture = value;
                        }
-#endif
                }
 
                internal static CultureInfo ConstructCurrentCulture ()
@@ -515,7 +514,7 @@ namespace System.Globalization
                        }
                }
 
-               internal void CheckNeutral ()
+               void CheckNeutral ()
                {
                }
 
@@ -1074,19 +1073,19 @@ namespace System.Globalization
                
                public static CultureInfo DefaultThreadCurrentCulture {
                        get {
-                               return Thread.default_culture;
+                               return s_DefaultThreadCurrentCulture;
                        }
                        set {
-                               Thread.default_culture = value;
+                               s_DefaultThreadCurrentCulture = value;
                        }
                }
                
                public static CultureInfo DefaultThreadCurrentUICulture {
                        get {
-                               return Thread.default_ui_culture;
+                               return s_DefaultThreadCurrentUICulture;
                        }
                        set {
-                               Thread.default_ui_culture = value;
+                               s_DefaultThreadCurrentUICulture = value;
                        }
                }
 
@@ -1096,6 +1095,19 @@ namespace System.Globalization
                        }
                }
 
+               internal static CultureInfo UserDefaultUICulture {
+                       get {
+                               return ConstructCurrentUICulture ();
+                       }
+               }
+
+               internal static CultureInfo UserDefaultCulture {
+                       get {
+                               return ConstructCurrentCulture ();
+                       }
+               }
+
+
 #region reference sources
                // TODO:
                internal static readonly bool IsTaiwanSku;
@@ -1148,6 +1160,19 @@ namespace System.Globalization
             return true;
         }
 
+        internal static bool VerifyCultureName(CultureInfo culture, bool throwException) {
+            Contract.Assert(culture!=null, "[CultureInfo.VerifyCultureName]culture!=null");
+
+            //If we have an instance of one of our CultureInfos, the user can't have changed the
+            //name and we know that all names are valid in files.
+            if (!culture.m_isInherited) {
+                return true;
+            }
+
+            return VerifyCultureName(culture.Name, throwException);
+
+        }
+
 #endregion
        }
 }
index d25432dcacdf559da372f14a60dde2ff5ca36fbb..205fadc0026b852b25a17c83bdd4cf76aaff0239 100644 (file)
@@ -427,20 +427,20 @@ namespace System.IO {
                static internal IEnumerable<FileSystemInfo> EnumerateFileSystemInfos (string full, string searchPattern, SearchOption searchOption)
                {
                        string path_with_pattern = Path.Combine (full, searchPattern);
-                       IntPtr handle;
+                       IntPtr handle = IntPtr.Zero;
                        MonoIOError error;
                        FileAttributes rattr;
                        bool subdirs = searchOption == SearchOption.AllDirectories;
 
                        Path.Validate (full);
                        
-                       string s = MonoIO.FindFirst (full, path_with_pattern, out rattr, out error, out handle);
-                       if (s == null)
-                               yield break;
-                       if (error != 0)
-                               throw MonoIO.GetException (Path.GetDirectoryName (path_with_pattern), (MonoIOError) error);
-
                        try {
+                               string s = MonoIO.FindFirst (full, path_with_pattern, out rattr, out error, out handle);
+                               if (s == null)
+                                       yield break;
+                               if (error != 0)
+                                       throw MonoIO.GetException (Path.GetDirectoryName (path_with_pattern), (MonoIOError) error);
+
                                do {
                                        if (((rattr & FileAttributes.ReparsePoint) == 0)){
                                                if ((rattr & FileAttributes.Directory) != 0)
@@ -455,7 +455,8 @@ namespace System.IO {
 
                                } while ((s = MonoIO.FindNext (handle, out rattr, out error)) != null);
                        } finally {
-                               MonoIO.FindClose (handle);
+                               if (handle != IntPtr.Zero)
+                                       MonoIO.FindClose (handle);
                        }
                }
                
index 7297e18d7a2b308ba5b500b812e3a6ca1d79a2c3..35a81c5e44984e708ae919fbd399daa9f5512fcb 100644 (file)
@@ -155,6 +155,10 @@ namespace System.IO
                        case MonoIOError.ERROR_NOT_SAME_DEVICE:
                                message = "Source and destination are not on the same device";
                                return new IOException (message, unchecked((int)0x80070000) | (int)error);
+
+                       case MonoIOError.ERROR_DIRECTORY:
+                               message = "The directory name is invalid";
+                               return new IOException (message, unchecked((int)0x80070000) | (int)error);
                                
                        default:
                                message = String.Format ("Win32 IO returned {0}. Path: {1}", error, path);
index 63756d190102372893732fd9e10aed7dabbf6526..2a78687ef36d21f80290a1816a747ef91eac5773 100644 (file)
@@ -217,8 +217,8 @@ namespace System.IO
                WAIT_TIMEOUT = 258,\r
                ERROR_NO_MORE_ITEMS = 259,\r
                ERROR_CANNOT_COPY = 266,\r
-               ERROR_DIRECTORY = 267,\r
-               ERROR_EAS_DIDNT_FIT = 275,\r
+       */      ERROR_DIRECTORY = 267,\r
+       /*      ERROR_EAS_DIDNT_FIT = 275,\r
                ERROR_EA_FILE_CORRUPT = 276,\r
                ERROR_EA_TABLE_FULL = 277,\r
                ERROR_INVALID_EA_HANDLE = 278,\r
index 09ea4405953409657b36364b9a504f94e3487064..138163779f85793b7847b1fb3e82ff6333f28ece 100644 (file)
@@ -140,6 +140,7 @@ namespace System.IO {
                {
                        int l = s.Length;
                        int sub = 0;
+                       int alt = 0;
                        int start = 0;
 
                        // Host prefix?
@@ -158,6 +159,8 @@ namespace System.IO {
                                
                                if (c != DirectorySeparatorChar && c != AltDirectorySeparatorChar)
                                        continue;
+                               if (DirectorySeparatorChar != AltDirectorySeparatorChar && c == AltDirectorySeparatorChar)
+                                       alt++;
                                if (i+1 == l)
                                        sub++;
                                else {
@@ -167,7 +170,7 @@ namespace System.IO {
                                }
                        }
 
-                       if (sub == 0)
+                       if (sub == 0 && alt == 0)
                                return s;
 
                        char [] copy = new char [l-sub];
@@ -885,5 +888,7 @@ namespace System.IO {
                                return DirectorySeparatorStr;
                        }
                }
+
+               internal const int MAX_PATH = 260;  // From WinDef.h
        }
 }
index 681e7cf80585557cd629dbfc42388a7a5045cd8d..793e36fd2a01cc033d059b58e1d6d939c34cba2a 100644 (file)
@@ -360,6 +360,18 @@ namespace System.Reflection.Emit {
                        if (ilgen != null)
                                ilgen.label_fixup (this);
                }
+
+               internal void ResolveUserTypes () {
+                       TypeBuilder.ResolveUserTypes (parameters);
+                       if (paramModReq != null) {
+                               foreach (var types in paramModReq)
+                                       TypeBuilder.ResolveUserTypes (types);
+                       }
+                       if (paramModOpt != null) {
+                               foreach (var types in paramModOpt)
+                                       TypeBuilder.ResolveUserTypes (types);
+                       }
+               }
                
                internal void GenerateDebugInfo (ISymbolWriter symbolWriter)
                {
index 053d8c831e4d05ea750b5b98b6324e0bb84d254f..f2fff7d7aa1ef9964d99e128965960aa869e2284 100644 (file)
@@ -220,6 +220,14 @@ namespace System.Reflection.Emit {
                                throw new InvalidOperationException ("Unable to change after type has been created.");
                }
 
+               internal void ResolveUserTypes () {
+                       type = TypeBuilder.ResolveUserType (type);
+                       TypeBuilder.ResolveUserTypes (modReq);
+                       TypeBuilder.ResolveUserTypes (modOpt);
+                       if (marshal_info != null)
+                               marshal_info.marshaltyperef = TypeBuilder.ResolveUserType (marshal_info.marshaltyperef);
+               }
+
                public override Module Module {
                        get {
                                return base.Module;
index 84c01c97bb73907a6d40f8d93d6c7f0f2f31bfbf..5545adca27657930a58d9aed580ece83fe515ea8 100644 (file)
@@ -364,7 +364,22 @@ namespace System.Reflection.Emit
                        if (ilgen != null)
                                ilgen.label_fixup (this);
                }
-               
+
+               internal void ResolveUserTypes () {
+                       rtype = TypeBuilder.ResolveUserType (rtype);
+                       TypeBuilder.ResolveUserTypes (parameters);
+                       TypeBuilder.ResolveUserTypes (returnModReq);
+                       TypeBuilder.ResolveUserTypes (returnModOpt);
+                       if (paramModReq != null) {
+                               foreach (var types in paramModReq)
+                                       TypeBuilder.ResolveUserTypes (types);
+                       }
+                       if (paramModOpt != null) {
+                               foreach (var types in paramModOpt)
+                                       TypeBuilder.ResolveUserTypes (types);
+                       }
+               }
+
                internal void GenerateDebugInfo (ISymbolWriter symbolWriter)
                {
                        if (ilgen != null && ilgen.HasDebugInfo) {
index 924eb674e154ef2c487f892e5d54a897fa502f3c..f921be221809245bf20484a0e5adc47f2fa47786 100644 (file)
@@ -361,6 +361,8 @@ namespace System.Reflection.Emit {
 
                public byte[] GetSignature ()
                {
+                       TypeBuilder.ResolveUserTypes (arguments);
+
                        switch (type) {
                        case SignatureHelperType.HELPER_LOCAL:
                                return get_signature_local ();
index 27553b18c7ea8bfcdab3acb52c447b299ed3c3ec..3972192308d8082a7c6be66c929a8989b4a85dce 100644 (file)
@@ -93,14 +93,8 @@ namespace System.Reflection.Emit
                }
                
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern void setup_internal_class (TypeBuilder tb);
+               private extern void setup_internal_class ();
                
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern void create_internal_class (TypeBuilder tb);
-               
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern void setup_generic_class ();
-
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                private extern void create_generic_class ();
 
@@ -117,13 +111,13 @@ namespace System.Reflection.Emit
                        this.nspace = String.Empty;
                        this.fullname = TypeIdentifiers.WithoutEscape(this.tname);
                        pmodule = mb;
-                       setup_internal_class (this);
+                       setup_internal_class ();
                }
 
                internal TypeBuilder (ModuleBuilder mb, string name, TypeAttributes attr, Type parent, Type[] interfaces, PackingSize packing_size, int type_size, Type nesting_type)
                {
                        int sep_index;
-                       this.parent = parent;
+                       this.parent = ResolveUserType (parent);
                        this.attrs = attr;
                        this.class_size = type_size;
                        this.packing_size = packing_size;
@@ -153,7 +147,7 @@ namespace System.Reflection.Emit
 
                        // skip .<Module> ?
                        table_idx = mb.get_next_table_index (this, 0x02, true);
-                       setup_internal_class (this);
+                       setup_internal_class ();
                        fullname = GetFullName ();
                }
 
@@ -672,7 +666,6 @@ namespace System.Reflection.Emit
                                fields = new FieldBuilder [1];
                                fields [0] = res;
                                num_fields ++;
-                               create_internal_class (this);
                        }
 
                        if (IsEnum) {
@@ -728,7 +721,7 @@ namespace System.Reflection.Emit
                }
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern TypeInfo create_runtime_class (TypeBuilder tb);
+               private extern TypeInfo create_runtime_class ();
 
                private bool is_nested_in (Type t)
                {
@@ -832,12 +825,54 @@ namespace System.Reflection.Emit
                                        ctor.fixup ();
                        }
 
-                       created = create_runtime_class (this);
+                       ResolveUserTypes ();
+
+                       created = create_runtime_class ();
                        if (created != null)
                                return created;
                        return this;
                }
 
+               void ResolveUserTypes () {
+                       parent = ResolveUserType (parent);
+                       ResolveUserTypes (interfaces);
+                       if (fields != null) {
+                               foreach (var fb in fields) {
+                                       if (fb != null)
+                                               fb.ResolveUserTypes ();
+                               }
+                       }
+                       if (methods != null) {
+                               foreach (var mb in methods) {
+                                       if (mb != null)
+                                               mb.ResolveUserTypes ();
+                               }
+                       }
+                       if (ctors != null) {
+                               foreach (var cb in ctors) {
+                                       if (cb != null)
+                                               cb.ResolveUserTypes ();
+                               }
+                       }
+               }
+
+               static internal void ResolveUserTypes (Type[] types) {
+                       if (types != null)
+                               for (int i = 0; i < types.Length; ++i)
+                                       types [i] = ResolveUserType (types [i]);
+               }
+
+               static internal Type ResolveUserType (Type t) {
+                       if (t != null && ((t.GetType ().Assembly != typeof (int).Assembly) || (t is TypeDelegator))) {
+                               t = t.UnderlyingSystemType;
+                               if (t != null && ((t.GetType ().Assembly != typeof (int).Assembly) || (t is TypeDelegator)))
+                                       throw new NotSupportedException ("User defined subclasses of System.Type are not yet supported.");
+                               return t;
+                       } else {
+                               return t;
+                       }
+               }
+
                internal void GenerateDebugInfo (ISymbolWriter symbolWriter)
                {
                        symbolWriter.OpenNamespace (this.Namespace);
@@ -1606,9 +1641,10 @@ namespace System.Reflection.Emit
                        } else {
                                this.parent = parent;
                        }
+                       this.parent = ResolveUserType (this.parent);
 
                        // will just set the parent-related bits if called a second time
-                       setup_internal_class (this);
+                       setup_internal_class ();
                }
 
                internal int get_next_table_index (object obj, int table, bool inc) {
@@ -1767,8 +1803,6 @@ namespace System.Reflection.Emit
                        if (names.Length == 0)
                                throw new ArgumentException ("names");
 
-                       setup_generic_class ();
-
                        generic_params = new GenericTypeParameterBuilder [names.Length];
                        for (int i = 0; i < names.Length; i++) {
                                string item = names [i];
index 45b9a2caef31e8cfe4281e8147c7015b83a59ccf..8772be59dac4a7cca6138ddeecc2f503c143d030 100644 (file)
@@ -50,7 +50,7 @@ namespace System.Reflection.Emit {
                string guid;
                string mcookie;
                string marshaltype;
-               Type marshaltyperef;
+               internal Type marshaltyperef;
                private int param_num;
                private bool has_size;
 #pragma warning restore 169, 414
index 7ce7241cc98c8851f6893ca193722e3c679c5f90..86241d82d2b223c5e2d93fd4047ce7e753ec3e8a 100644 (file)
@@ -446,11 +446,9 @@ namespace System.Reflection {
                        get {
                                return (cultureinfo == null)? null : cultureinfo.Name;
                        }
-#if NETSTANDARD
                        set {
                                throw new NotImplementedException ();
                        }
-#endif
                }
 
                [ComVisibleAttribute(false)]
index d1958f33eb26c47bb90f110544c0a88326d30685..d7128abc33553234622f969754c0ffe932741ded 100644 (file)
@@ -37,10 +37,10 @@ using System;
 using System.Security;
 using System.Reflection;
 using System.Threading;
+using System.Runtime.InteropServices.ComTypes;
 
 using System.Runtime.ConstrainedExecution;
 #if !FULL_AOT_RUNTIME
-using System.Runtime.InteropServices.ComTypes;
 using Mono.Interop;
 #endif
 
@@ -197,9 +197,11 @@ namespace System.Runtime.InteropServices
                        return CreateAggregatedObject (pOuter, (object)o);
                }
 
-#if !FULL_AOT_RUNTIME
                public static object CreateWrapperOfType (object o, Type t)
                {
+#if FULL_AOT_RUNTIME
+                       throw new PlatformNotSupportedException ();
+#else
                        __ComObject co = o as __ComObject;
                        if (co == null)
                                throw new ArgumentException ("o must derive from __ComObject", "o");
@@ -213,12 +215,12 @@ namespace System.Runtime.InteropServices
                        }
 
                        return ComInteropProxy.GetProxy (co.IUnknown, t).GetTransparentProxy ();
+#endif
                }
 
                public static TWrapper CreateWrapperOfType<T, TWrapper> (T o) {
                        return (TWrapper)CreateWrapperOfType ((object)o, typeof (TWrapper));
                }
-#endif
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                [ComVisible (true)]
@@ -335,15 +337,16 @@ namespace System.Runtime.InteropServices
                                return GetCCW (o, T);
                }
 #endif
+#endif // !FULL_AOT_RUNTIME
 
                public static IntPtr GetComInterfaceForObject (object o, Type T)
                {
-#if !MOBILE
+#if MOBILE
+                       throw new PlatformNotSupportedException ();
+#else
                        IntPtr pItf = GetComInterfaceForObjectInternal (o, T);
                        AddRef (pItf);
                        return pItf;
-#else
-                       throw new NotImplementedException ();
 #endif
                }
 
@@ -357,6 +360,7 @@ namespace System.Runtime.InteropServices
                        return GetComInterfaceForObject ((object)o, typeof (T));
                }
 
+#if !FULL_AOT_RUNTIME
                [MonoTODO]
                public static IntPtr GetComInterfaceForObjectInContext (object o, Type t)
                {
@@ -395,12 +399,6 @@ namespace System.Runtime.InteropServices
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
-               public static int GetExceptionCode()
-               {
-                       throw new NotImplementedException ();
-               }
-
                [MonoTODO]
                [ComVisible (true)]
                public static IntPtr GetExceptionPointers()
@@ -417,26 +415,35 @@ namespace System.Runtime.InteropServices
                }
 #endif // !FULL_AOT_RUNTIME
 
-#if !FULL_AOT_RUNTIME
+               public static int GetExceptionCode ()
+               {
+                       throw new PlatformNotSupportedException ();
+               }
+
                public static int GetHRForException (Exception e)
                {
+                       if (e == null) return 0;
+
 #if FEATURE_COMINTEROP
                        var errorInfo = new ManagedErrorInfo(e);
                        SetErrorInfo (0, errorInfo);
+#endif
 
                        return e._HResult;
-#else                  
-                       return -1;
-#endif
                }
 
                [MonoTODO]
                [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
                public static int GetHRForLastWin32Error()
                {
+#if FULL_AOT_RUNTIME
+                       throw new PlatformNotSupportedException ();
+#else
                        throw new NotImplementedException ();
+#endif
                }
 
+#if !FULL_AOT_RUNTIME
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                private extern static IntPtr GetIDispatchForObjectInternal (object o);
 
@@ -460,17 +467,6 @@ namespace System.Runtime.InteropServices
                        throw new NotImplementedException ();
                }
 
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               private extern static IntPtr GetIUnknownForObjectInternal (object o);
-
-               public static IntPtr GetIUnknownForObject (object o)
-               {
-                       IntPtr pUnk = GetIUnknownForObjectInternal (o);
-                       // Internal method does not AddRef
-                       AddRef (pUnk);
-                       return pUnk;
-               }
-
                [MonoTODO]
                public static IntPtr GetIUnknownForObjectInContext (object o)
                {
@@ -490,25 +486,48 @@ namespace System.Runtime.InteropServices
                        throw new NotImplementedException ();
                }
 
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               private extern static IntPtr GetIUnknownForObjectInternal (object o);
+
+#endif // !FULL_AOT_RUNTIME
+
+               public static IntPtr GetIUnknownForObject (object o)
+               {
+#if FULL_AOT_RUNTIME
+                       throw new PlatformNotSupportedException ();
+#else
+                       IntPtr pUnk = GetIUnknownForObjectInternal (o);
+                       // Internal method does not AddRef
+                       AddRef (pUnk);
+                       return pUnk;
+#endif
+               }
+
                public static void GetNativeVariantForObject (object obj, IntPtr pDstNativeVariant)
                {
+#if FULL_AOT_RUNTIME
+                       throw new PlatformNotSupportedException ();
+#else
                        Variant vt = new Variant();
                        vt.SetValue(obj);
                        Marshal.StructureToPtr(vt, pDstNativeVariant, false);
+#endif
                }
 
                public static void GetNativeVariantForObject<T> (T obj, IntPtr pDstNativeVariant) {
                        GetNativeVariantForObject ((object)obj, pDstNativeVariant);
                }
 
-#if !MOBILE
+#if !MOBILE && !FULL_AOT_RUNTIME
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                private static extern object GetObjectForCCW (IntPtr pUnk);
 #endif
 
                public static object GetObjectForIUnknown (IntPtr pUnk)
                {
-#if !MOBILE
+#if MOBILE || FULL_AOT_RUNTIME
+                       throw new PlatformNotSupportedException ();
+#else
                        object obj = GetObjectForCCW (pUnk);
                        // was not a CCW
                        if (obj == null) {
@@ -516,24 +535,34 @@ namespace System.Runtime.InteropServices
                                obj = proxy.GetTransparentProxy ();
                        }
                        return obj;
-#else
-                       throw new NotImplementedException ();
 #endif
                }
 
                public static object GetObjectForNativeVariant (IntPtr pSrcNativeVariant)
                {
+#if FULL_AOT_RUNTIME
+                       throw new PlatformNotSupportedException ();
+#else
                        Variant vt = (Variant)Marshal.PtrToStructure(pSrcNativeVariant, typeof(Variant));
                        return vt.GetValue();
+#endif
                }
 
-               public static T GetObjectForNativeVariant<T> (IntPtr pSrcNativeVariant) {
+               public static T GetObjectForNativeVariant<T> (IntPtr pSrcNativeVariant)
+               {
+#if FULL_AOT_RUNTIME
+                       throw new PlatformNotSupportedException ();
+#else
                        Variant vt = (Variant)Marshal.PtrToStructure(pSrcNativeVariant, typeof(Variant));
                        return (T)vt.GetValue();
+#endif
                }
 
                public static object[] GetObjectsForNativeVariants (IntPtr aSrcNativeVariant, int cVars)
                {
+#if FULL_AOT_RUNTIME
+                       throw new PlatformNotSupportedException ();
+#else
                        if (cVars < 0)
                                throw new ArgumentOutOfRangeException ("cVars", "cVars cannot be a negative number.");
                        object[] objects = new object[cVars];
@@ -541,9 +570,14 @@ namespace System.Runtime.InteropServices
                                objects[i] = GetObjectForNativeVariant ((IntPtr)(aSrcNativeVariant.ToInt64 () +
                                        i * SizeOf (typeof(Variant))));
                        return objects;
+#endif
                }
 
-               public static T[] GetObjectsForNativeVariants<T> (IntPtr aSrcNativeVariant, int cVars) {
+               public static T[] GetObjectsForNativeVariants<T> (IntPtr aSrcNativeVariant, int cVars)
+               {
+#if FULL_AOT_RUNTIME
+                       throw new PlatformNotSupportedException ();
+#else
                        if (cVars < 0)
                                throw new ArgumentOutOfRangeException ("cVars", "cVars cannot be a negative number.");
                        T[] objects = new T[cVars];
@@ -551,14 +585,20 @@ namespace System.Runtime.InteropServices
                                objects[i] = GetObjectForNativeVariant<T> ((IntPtr)(aSrcNativeVariant.ToInt64 () +
                                        i * SizeOf (typeof(Variant))));
                        return objects;
+#endif
                }
 
                [MonoTODO]
                public static int GetStartComSlot (Type t)
                {
+#if FULL_AOT_RUNTIME
+                       throw new PlatformNotSupportedException ();
+#else
                        throw new NotImplementedException ();
+#endif
                }
 
+#if !FULL_AOT_RUNTIME
                [MonoTODO]
                [Obsolete ("This method has been deprecated")]
                public static Thread GetThreadFromFiberCookie (int cookie)
@@ -585,12 +625,6 @@ namespace System.Runtime.InteropServices
                        throw new NotImplementedException ();
                }
 
-               public static Type GetTypeFromCLSID (Guid clsid)
-               {
-                       throw new NotImplementedException ();                   
-               }
-
-#if !FULL_AOT_RUNTIME
                [Obsolete]
                [MonoTODO]
                public static string GetTypeInfoName (UCOMITypeInfo pTI)
@@ -598,11 +632,6 @@ namespace System.Runtime.InteropServices
                        throw new NotImplementedException ();
                }
 
-               public static string GetTypeInfoName (ITypeInfo typeInfo)
-               {
-                       throw new NotImplementedException ();
-               }
-
                [Obsolete]
                [MonoTODO]
                public static Guid GetTypeLibGuid (UCOMITypeLib pTLB)
@@ -654,12 +683,6 @@ namespace System.Runtime.InteropServices
                        throw new NotImplementedException ();
                }
 
-               public static object GetUniqueObjectForIUnknown (IntPtr unknown)
-               {
-                       throw new NotImplementedException ();
-               }
-#endif
-
                [MonoTODO]
                [Obsolete ("This method has been deprecated")]
                public static IntPtr GetUnmanagedThunkForManagedMethodPtr (IntPtr pfnMethodToWrap, IntPtr pbSignature, int cbSignature)
@@ -667,16 +690,6 @@ namespace System.Runtime.InteropServices
                        throw new NotImplementedException ();
                }
 
-#if !MOBILE
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern static bool IsComObject (object o);
-#else
-               public static bool IsComObject (object o)
-               {
-                       throw new NotImplementedException ();
-               }
-#endif         
-
                [MonoTODO]
                public static bool IsTypeVisibleFromCom (Type t)
                {
@@ -688,6 +701,31 @@ namespace System.Runtime.InteropServices
                {
                        throw new NotImplementedException ();
                }
+#endif // !FULL_AOT_RUNTIME
+
+               public static Type GetTypeFromCLSID (Guid clsid)
+               {
+                       throw new PlatformNotSupportedException ();
+               }
+
+               public static string GetTypeInfoName (ITypeInfo typeInfo)
+               {
+                       throw new PlatformNotSupportedException ();
+               }
+
+               public static object GetUniqueObjectForIUnknown (IntPtr unknown)
+               {
+                       throw new PlatformNotSupportedException ();
+               }
+
+#if !MOBILE
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               public extern static bool IsComObject (object o);
+#else
+               public static bool IsComObject (object o)
+               {
+                       throw new PlatformNotSupportedException ();
+               }
 #endif
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
@@ -950,16 +988,22 @@ namespace System.Runtime.InteropServices
 #if !FULL_AOT_RUNTIME
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                private extern static int ReleaseComObjectInternal (object co);
+#endif
 
                public static int ReleaseComObject (object o)
                {
+#if FULL_AOT_RUNTIME
+                       throw new PlatformNotSupportedException ();
+#else
                        if (o == null)
                                throw new ArgumentException ("Value cannot be null.", "o");
                        if (!IsComObject (o))
                                throw new ArgumentException ("Value must be a Com object.", "o");
                        return ReleaseComObjectInternal (o);
+#endif
                }
 
+#if !FULL_AOT_RUNTIME
                [Obsolete]
                [MonoTODO]
                public static void ReleaseThreadCache()
@@ -1630,13 +1674,11 @@ namespace System.Runtime.InteropServices
 #endif
                }
 
-#if !FULL_AOT_RUNTIME
                public static int FinalReleaseComObject (object o)
                {
                        while (ReleaseComObject (o) != 0);
                        return 0;
                }
-#endif
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                private static extern Delegate GetDelegateForFunctionPointerInternal (IntPtr ptr, Type t);
index b5b59a1ae81ffb3f37822fd47ba5619f08d7469a..a01d526ff2588d5e1d32eea908836061f47b91c2 100644 (file)
@@ -122,7 +122,7 @@ namespace System.Runtime.InteropServices
                                        old_state = _state;
 
                                        if ((old_state & (int) State.Closed) != 0)
-                                               throw new ObjectDisposedException ("handle");
+                                               throw new ObjectDisposedException (null, "Safe handle has been closed");
 
                                        new_state = old_state + RefCount_One;
                                } while (Interlocked.CompareExchange (ref _state, new_state, old_state) != old_state);
@@ -198,7 +198,7 @@ namespace System.Runtime.InteropServices
                                         * hitting zero though -- that can happen if SetHandleAsInvalid is
                                         * used). */
                                        if ((old_state & RefCount_Mask) == 0)
-                                               throw new ObjectDisposedException ("handle");
+                                               throw new ObjectDisposedException (null, "Safe handle has been closed");
 
                                        if ((old_state & RefCount_Mask) != RefCount_One)
                                                perform_release = false;
index 7e83a6cacf0a297bccf6973c93a0762b405fe84f..b951a8141d5d38927a3798202cdfae98f9751474 100644 (file)
@@ -129,6 +129,11 @@ namespace System.Security.AccessControl
                {
                        Persist (name, includeSections, null);
                }
+
+               internal void Persist (SafeHandle handle)
+               {
+                       PersistModifications (handle);
+               }
                
                internal void PersistModifications (SafeHandle handle)
                {
diff --git a/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.common.cs b/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.common.cs
new file mode 100644 (file)
index 0000000..f4a9d9c
--- /dev/null
@@ -0,0 +1,134 @@
+//
+// CryptoConfig.cs: Handles cryptographic implementations and OIDs mappings.
+//
+// Author:
+//     Sebastien Pouliot (sebastien@ximian.com)
+//     Tim Coleman (tim@timcoleman.com)
+//
+// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
+// Copyright (C) Tim Coleman, 2004
+// Copyright (C) 2004-2007, 2009 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Security.Cryptography {
+
+       public partial class CryptoConfig {
+
+               public static byte[] EncodeOID (string str)
+               {
+                       if (str == null)
+                               throw new ArgumentNullException ("str");
+                       char[] delim = { '.' };
+                       string[] parts = str.Split (delim);
+                       // according to X.208 n is always at least 2
+                       if (parts.Length < 2) {
+                               throw new CryptographicUnexpectedOperationException (
+                                       Locale.GetText ("OID must have at least two parts"));
+                       }
+
+                       // we're sure that the encoded OID is shorter than its string representation
+                       byte[] oid = new byte [str.Length];
+                       // now encoding value
+                       try {
+                               byte part0 = Convert.ToByte (parts [0]);
+                               // OID[0] > 2 is invalid but "supported" in MS BCL
+                               // uncomment next line to trap this error
+                               // if (part0 > 2) throw new CryptographicUnexpectedOperationException ();
+                               byte part1 = Convert.ToByte (parts [1]);
+                               // OID[1] >= 40 is illegal for OID[0] < 2 because of the % 40
+                               // however the syntax is "supported" in MS BCL
+                               // uncomment next 2 lines to trap this error
+                               //if ((part0 < 2) && (part1 >= 40))
+                               //      throw new CryptographicUnexpectedOperationException ();
+                               oid[2] = Convert.ToByte (part0 * 40 + part1);
+                       }
+                       catch {
+                               throw new CryptographicUnexpectedOperationException (
+                                       Locale.GetText ("Invalid OID"));
+                       }
+                       int j = 3;
+                       for (int i = 2; i < parts.Length; i++) {
+                               long x = Convert.ToInt64 (parts [i]);
+                               if (x > 0x7F) {
+                                       byte[] num = EncodeLongNumber (x);
+                                       Buffer.BlockCopy (num, 0, oid, j, num.Length);
+                                       j += num.Length;
+                               }
+                               else
+                                       oid[j++] = Convert.ToByte (x);
+                       }
+
+                       int k = 2;
+                       // copy the exact number of byte required
+                       byte[] oid2 = new byte [j];
+                       oid2[0] = 0x06; // always - this tag means OID
+                       // Length (of value)
+                       if (j > 0x7F) {
+                               // for compatibility with MS BCL
+                               throw new CryptographicUnexpectedOperationException (
+                                       Locale.GetText ("OID > 127 bytes"));
+                               // comment exception and uncomment next 3 lines to remove restriction
+                               //byte[] num = EncodeLongNumber (j);
+                               //Buffer.BlockCopy (num, 0, oid, j, num.Length);
+                               //k = num.Length + 1;
+                       }
+                       else
+                               oid2 [1] = Convert.ToByte (j - 2); 
+
+                       Buffer.BlockCopy (oid, k, oid2, k, j - k);
+                       return oid2;
+               }
+
+               // encode (7bits array) number greater than 127
+               private static byte[] EncodeLongNumber (long x)
+               {
+                       // for MS BCL compatibility
+                       // comment next two lines to remove restriction
+                       if ((x > Int32.MaxValue) || (x < Int32.MinValue))
+                               throw new OverflowException (Locale.GetText ("Part of OID doesn't fit in Int32"));
+
+                       long y = x;
+                       // number of bytes required to encode this number
+                       int n = 1;
+                       while (y > 0x7F) {
+                               y = y >> 7;
+                               n++;
+                       }
+                       byte[] num = new byte [n];
+                       // encode all bytes 
+                       for (int i = 0; i < n; i++) {
+                               y = x >> (7 * i);
+                               y = y & 0x7F;
+                               if (i != 0)
+                                       y += 0x80;
+                               num[n-i-1] = Convert.ToByte (y);
+                       }
+                       return num;
+               }
+
+               [MonoLimitation ("nothing is FIPS certified so it never make sense to restrict to this (empty) subset")]
+               public static bool AllowOnlyFipsAlgorithms {
+                       get { return false; }
+               }
+       }
+}
+
index 369455581dac5ea9c2f0c06cf4d1582d643f6b25..e74123e761164c93c84fb94dc5720358f08f4537 100644 (file)
@@ -73,7 +73,10 @@ public partial class CryptoConfig {
        static Type defaultMAC3DES = typeof (MACTripleDES);
        // LAMESPEC: undocumented classes (also undocumented in CryptoConfig ;-)
        static Type defaultDSASigDesc = typeof (DSASignatureDescription);
-       static Type defaultRSASigDesc = typeof (RSAPKCS1SHA1SignatureDescription);
+       static Type defaultRSAPKCS1SHA1SigDesc = typeof (RSAPKCS1SHA1SignatureDescription);
+       static Type defaultRSAPKCS1SHA256SigDesc = typeof (RSAPKCS1SHA256SignatureDescription);
+       static Type defaultRSAPKCS1SHA384SigDesc = typeof (RSAPKCS1SHA384SignatureDescription);
+       static Type defaultRSAPKCS1SHA512SigDesc = typeof (RSAPKCS1SHA512SignatureDescription);
        static Type defaultRIPEMD160 = typeof (RIPEMD160Managed);
        static Type defaultHMACMD5 = typeof (HMACMD5);
        static Type defaultHMACRIPEMD160 = typeof (HMACRIPEMD160);
@@ -185,6 +188,9 @@ public partial class CryptoConfig {
        // LAMESPEC: undocumented URLs in CryptoConfig
        private const string urlDSASHA1 = urlXmlDsig + "dsa-sha1";                      // no space
        private const string urlRSASHA1 = urlXmlDsig + "rsa-sha1";                      // no space
+       private const string urlRSASHA256 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";                        // no space
+       private const string urlRSASHA384 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384";                        // no space
+       private const string urlRSASHA512 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512";                        // no space
        private const string urlSHA1 = urlXmlDsig + "sha1";                             // no space
        private const string urlC14N = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"; 
        private const string urlC14NWithComments = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments";
@@ -196,6 +202,7 @@ public partial class CryptoConfig {
        private const string urlExcC14NWithComments = "http://www.w3.org/2001/10/xml-exc-c14n#WithComments";
        private const string urlExcC14N = "http://www.w3.org/2001/10/xml-exc-c14n#";
        private const string urlSHA256 = "http://www.w3.org/2001/04/xmlenc#sha256";
+       private const string urlSHA384 = "http://www.w3.org/2001/04/xmldsig-more#sha384";
        private const string urlSHA512 = "http://www.w3.org/2001/04/xmlenc#sha512";
        private const string urlHMACSHA256 = "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256";
        private const string urlHMACSHA384 = "http://www.w3.org/2001/04/xmldsig-more#hmac-sha384";
@@ -360,7 +367,10 @@ public partial class CryptoConfig {
                // add some of the XMLDSIG urls into machine.config (and they make a LOT
                // of sense for implementing XMLDSIG in System.Security.Cryptography.Xml)
                algorithms.Add (urlDSASHA1, defaultDSASigDesc); 
-               algorithms.Add (urlRSASHA1, defaultRSASigDesc);
+               algorithms.Add (urlRSASHA1, defaultRSAPKCS1SHA1SigDesc);
+               algorithms.Add (urlRSASHA256, defaultRSAPKCS1SHA256SigDesc);
+               algorithms.Add (urlRSASHA384, defaultRSAPKCS1SHA384SigDesc);
+               algorithms.Add (urlRSASHA512, defaultRSAPKCS1SHA512SigDesc);
                algorithms.Add (urlSHA1, defaultSHA1);
                unresolved_algorithms.Add (urlC14N, defaultC14N);
                unresolved_algorithms.Add (urlC14NWithComments, defaultC14NWithComments);
@@ -372,7 +382,7 @@ public partial class CryptoConfig {
                unresolved_algorithms.Add (urlExcC14NWithComments, defaultExcC14NWithComments);
                unresolved_algorithms.Add (urlXmlDecryption, defaultXmlDecryption);
                algorithms.Add (urlSHA256, defaultSHA256);
-               // xmlenc does not include a definition for SHA384
+               algorithms.Add (urlSHA384, defaultSHA384);
                algorithms.Add (urlSHA512, defaultSHA512);
                algorithms.Add (urlHMACSHA256, defaultHMACSHA256);
                algorithms.Add (urlHMACSHA384, defaultHMACSHA384);
@@ -430,14 +440,20 @@ public partial class CryptoConfig {
                oid.Add (nameSHA256, oidSHA256);
                oid.Add (nameSHA256a, oidSHA256);
                oid.Add (nameSHA256c, oidSHA256);
+               oid.Add (nameSHA256Cng, oidSHA256);
+               oid.Add (nameSHA256Provider, oidSHA256);
 
                oid.Add (nameSHA384, oidSHA384);
                oid.Add (nameSHA384a, oidSHA384);
                oid.Add (nameSHA384c, oidSHA384);
+               oid.Add (nameSHA384Cng, oidSHA384);
+               oid.Add (nameSHA384Provider, oidSHA384);
 
                oid.Add (nameSHA512, oidSHA512);
                oid.Add (nameSHA512a, oidSHA512);
                oid.Add (nameSHA512c, oidSHA512);
+               oid.Add (nameSHA512Cng, oidSHA512);
+               oid.Add (nameSHA512Provider, oidSHA512);
 
                oid.Add (nameRIPEMD160, oidRIPEMD160);
                oid.Add (nameRIPEMD160a, oidRIPEMD160);
index 9282679690814c32a72134538a7fba718d95e254..29322f74ea8b8c8c30e82044455472439bcd7eb1 100755 (executable)
@@ -133,9 +133,19 @@ namespace System.Security.Cryptography {
                        case "system.security.cryptography.rsapkcs1sha1signaturedescription":
                        case "http://www.w3.org/2000/09/xmldsig#rsa-sha1":
                                return new RSAPKCS1SHA1SignatureDescription ();
+                       case "system.security.cryptography.rsapkcs1sha256signaturedescription":
+                       case "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256":
+                               return new RSAPKCS1SHA256SignatureDescription ();
+                       case "system.security.cryptography.rsapkcs1sha384signaturedescription":
+                       case "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384":
+                               return new RSAPKCS1SHA384SignatureDescription ();
+                       case "system.security.cryptography.rsapkcs1sha512signaturedescription":
+                       case "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512":
+                               return new RSAPKCS1SHA512SignatureDescription ();
                        case "system.security.cryptography.hashalgorithm":
                        case "system.security.cryptography.sha1":
                        case "system.security.cryptography.sha1cryptoserviceprovider":
+                       case "system.security.cryptography.sha1cng":
                        case "sha1":
                        case "sha":
                        case "http://www.w3.org/2000/09/xmldsig#sha1":
@@ -144,17 +154,24 @@ namespace System.Security.Cryptography {
                                return new SHA1Managed ();
                        case "system.security.cryptography.sha256managed":
                        case "system.security.cryptography.sha256":
+                       case "system.security.cryptography.sha256cryptoserviceprovider":
+                       case "system.security.cryptography.sha256cng":
                        case "sha256":
                        case "sha-256":
                        case "http://www.w3.org/2001/04/xmlenc#sha256":
                                return new SHA256Managed ();
                        case "system.security.cryptography.sha384managed":
                        case "system.security.cryptography.sha384":
+                       case "system.security.cryptography.sha384cryptoserviceprovider":
+                       case "system.security.cryptography.sha384cng":
                        case "sha384":
                        case "sha-384":
+                       case "http://www.w3.org/2001/04/xmldsig-more#sha384":
                                return new SHA384Managed ();
                        case "system.security.cryptography.sha512managed":
                        case "system.security.cryptography.sha512":
+                       case "system.security.cryptography.sha512cryptoserviceprovider":
+                       case "system.security.cryptography.sha512cng":
                        case "sha512":
                        case "sha-512":
                        case "http://www.w3.org/2001/04/xmlenc#sha512":
@@ -201,6 +218,7 @@ namespace System.Security.Cryptography {
 
                        switch (name.ToLowerInvariant ()) {
                        case "system.security.cryptography.sha1cryptoserviceprovider":
+                       case "system.security.cryptography.sha1cng":
                        case "system.security.cryptography.sha1managed":
                        case "system.security.cryptography.sha1":
                        case "sha1":
@@ -209,14 +227,20 @@ namespace System.Security.Cryptography {
                        case "system.security.cryptography.md5":
                        case "md5":
                                return "1.2.840.113549.2.5";
+                       case "system.security.cryptography.sha256cryptoserviceprovider":
+                       case "system.security.cryptography.sha256cng":
                        case "system.security.cryptography.sha256managed":
                        case "system.security.cryptography.sha256":
                        case "sha256":
                                return "2.16.840.1.101.3.4.2.1";
+                       case "system.security.cryptography.sha384cryptoserviceprovider":
+                       case "system.security.cryptography.sha384cng":
                        case "system.security.cryptography.sha384managed":
                        case "system.security.cryptography.sha384":
                        case "sha384":
                                return "2.16.840.1.101.3.4.2.2";
+                       case "system.security.cryptography.sha512cryptoserviceprovider":
+                       case "system.security.cryptography.sha512cng":
                        case "system.security.cryptography.sha512managed":
                        case "system.security.cryptography.sha512":
                        case "sha512":
diff --git a/mcs/class/corlib/System.Security.Cryptography/CryptoConfig_2_1.cs b/mcs/class/corlib/System.Security.Cryptography/CryptoConfig_2_1.cs
deleted file mode 100644 (file)
index f4a9d9c..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-//
-// CryptoConfig.cs: Handles cryptographic implementations and OIDs mappings.
-//
-// Author:
-//     Sebastien Pouliot (sebastien@ximian.com)
-//     Tim Coleman (tim@timcoleman.com)
-//
-// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
-// Copyright (C) Tim Coleman, 2004
-// Copyright (C) 2004-2007, 2009 Novell, Inc (http://www.novell.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-namespace System.Security.Cryptography {
-
-       public partial class CryptoConfig {
-
-               public static byte[] EncodeOID (string str)
-               {
-                       if (str == null)
-                               throw new ArgumentNullException ("str");
-                       char[] delim = { '.' };
-                       string[] parts = str.Split (delim);
-                       // according to X.208 n is always at least 2
-                       if (parts.Length < 2) {
-                               throw new CryptographicUnexpectedOperationException (
-                                       Locale.GetText ("OID must have at least two parts"));
-                       }
-
-                       // we're sure that the encoded OID is shorter than its string representation
-                       byte[] oid = new byte [str.Length];
-                       // now encoding value
-                       try {
-                               byte part0 = Convert.ToByte (parts [0]);
-                               // OID[0] > 2 is invalid but "supported" in MS BCL
-                               // uncomment next line to trap this error
-                               // if (part0 > 2) throw new CryptographicUnexpectedOperationException ();
-                               byte part1 = Convert.ToByte (parts [1]);
-                               // OID[1] >= 40 is illegal for OID[0] < 2 because of the % 40
-                               // however the syntax is "supported" in MS BCL
-                               // uncomment next 2 lines to trap this error
-                               //if ((part0 < 2) && (part1 >= 40))
-                               //      throw new CryptographicUnexpectedOperationException ();
-                               oid[2] = Convert.ToByte (part0 * 40 + part1);
-                       }
-                       catch {
-                               throw new CryptographicUnexpectedOperationException (
-                                       Locale.GetText ("Invalid OID"));
-                       }
-                       int j = 3;
-                       for (int i = 2; i < parts.Length; i++) {
-                               long x = Convert.ToInt64 (parts [i]);
-                               if (x > 0x7F) {
-                                       byte[] num = EncodeLongNumber (x);
-                                       Buffer.BlockCopy (num, 0, oid, j, num.Length);
-                                       j += num.Length;
-                               }
-                               else
-                                       oid[j++] = Convert.ToByte (x);
-                       }
-
-                       int k = 2;
-                       // copy the exact number of byte required
-                       byte[] oid2 = new byte [j];
-                       oid2[0] = 0x06; // always - this tag means OID
-                       // Length (of value)
-                       if (j > 0x7F) {
-                               // for compatibility with MS BCL
-                               throw new CryptographicUnexpectedOperationException (
-                                       Locale.GetText ("OID > 127 bytes"));
-                               // comment exception and uncomment next 3 lines to remove restriction
-                               //byte[] num = EncodeLongNumber (j);
-                               //Buffer.BlockCopy (num, 0, oid, j, num.Length);
-                               //k = num.Length + 1;
-                       }
-                       else
-                               oid2 [1] = Convert.ToByte (j - 2); 
-
-                       Buffer.BlockCopy (oid, k, oid2, k, j - k);
-                       return oid2;
-               }
-
-               // encode (7bits array) number greater than 127
-               private static byte[] EncodeLongNumber (long x)
-               {
-                       // for MS BCL compatibility
-                       // comment next two lines to remove restriction
-                       if ((x > Int32.MaxValue) || (x < Int32.MinValue))
-                               throw new OverflowException (Locale.GetText ("Part of OID doesn't fit in Int32"));
-
-                       long y = x;
-                       // number of bytes required to encode this number
-                       int n = 1;
-                       while (y > 0x7F) {
-                               y = y >> 7;
-                               n++;
-                       }
-                       byte[] num = new byte [n];
-                       // encode all bytes 
-                       for (int i = 0; i < n; i++) {
-                               y = x >> (7 * i);
-                               y = y & 0x7F;
-                               if (i != 0)
-                                       y += 0x80;
-                               num[n-i-1] = Convert.ToByte (y);
-                       }
-                       return num;
-               }
-
-               [MonoLimitation ("nothing is FIPS certified so it never make sense to restrict to this (empty) subset")]
-               public static bool AllowOnlyFipsAlgorithms {
-                       get { return false; }
-               }
-       }
-}
-
index b65d55460d4fde6b99f69ec029a2da815ff45ea5..64826f938eb50a5a2568a0628d311a5b17f0ddcb 100644 (file)
@@ -83,7 +83,13 @@ namespace System.Security.Policy {
                        if (url.Length == 0)
                                return new Zone (z);
 
-                       Uri uri = new Uri (url);
+                       Uri uri = null;
+                       try {
+                               uri = new Uri (url);
+                       }
+                       catch {
+                               return new Zone (z);
+                       }
                        // TODO: apply zone configuration
                        // this is the only way to use the Trusted and Untrusted zones
 
index f64237aaf6a7ef85e98ee51b2fd4a52174c3039c..0d87d5624e976237fd27f47acfba26b4c8a591d2 100644 (file)
@@ -157,7 +157,11 @@ internal class Latin1Encoding : Encoding
                                        buffer = EncoderFallback.CreateFallbackBuffer ();
                                if (Char.IsSurrogate (ch) && count > 1 &&
                                    Char.IsSurrogate (chars [charIndex]))
-                                       buffer.Fallback (ch, chars [charIndex], charIndex++ - 1);
+                               {
+                                       buffer.Fallback (ch, chars [charIndex], charIndex - 1);
+                                       charIndex++;
+                                       count--;
+                               }
                                else
                                        buffer.Fallback (ch, charIndex - 1);
                                if (fallback_chars == null || fallback_chars.Length < buffer.Remaining)
diff --git a/mcs/class/corlib/System.Threading/EventWaitHandle.cs b/mcs/class/corlib/System.Threading/EventWaitHandle.cs
deleted file mode 100644 (file)
index 0594eb1..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-//
-// System.Threading.EventWaitHandle.cs
-//
-// Author:
-//     Dick Porter (dick@ximian.com)
-//
-// (C) Ximian, Inc.    (http://www.ximian.com)
-// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System.IO;
-using System.Runtime.InteropServices;
-using System.Security.AccessControl;
-
-namespace System.Threading
-{
-       [ComVisible (true)]
-       public class EventWaitHandle : WaitHandle
-       {
-               private EventWaitHandle (IntPtr handle)
-               {
-                       Handle = handle;
-               }
-
-               static bool IsManualReset (EventResetMode mode)
-               {
-                       if ((mode < EventResetMode.AutoReset) || (mode > EventResetMode.ManualReset))
-                               throw new ArgumentException ("mode");
-                       return (mode == EventResetMode.ManualReset);
-               }
-               
-               public EventWaitHandle (bool initialState, EventResetMode mode)
-               {
-                       bool created;
-                       bool manual = IsManualReset (mode);
-                       Handle = NativeEventCalls.CreateEvent_internal (manual, initialState, null, out created);
-               }
-               
-#if !MOBILE
-               
-               public EventWaitHandle (bool initialState, EventResetMode mode,
-                                       string name)
-               {
-                       bool created;
-                       bool manual = IsManualReset (mode);
-                       Handle = NativeEventCalls.CreateEvent_internal (manual, initialState, name, out created);
-               }
-               
-               public EventWaitHandle (bool initialState, EventResetMode mode,
-                                       string name, out bool createdNew)
-               {
-                       bool manual = IsManualReset (mode);
-                       Handle = NativeEventCalls.CreateEvent_internal (manual, initialState, name, out createdNew);
-               }
-
-
-               [MonoTODO ("Use access control in CreateEvent_internal")]
-               public EventWaitHandle (bool initialState, EventResetMode mode,
-                                       string name, out bool createdNew,
-                                       EventWaitHandleSecurity eventSecurity)
-               {
-                       bool manual = IsManualReset (mode);
-                       Handle = NativeEventCalls.CreateEvent_internal (manual, initialState, name, out createdNew);
-               }
-               
-               public EventWaitHandleSecurity GetAccessControl ()
-               {
-                       return new EventWaitHandleSecurity (SafeWaitHandle,
-                                                           AccessControlSections.Owner |
-                                                           AccessControlSections.Group |
-                                                           AccessControlSections.Access);
-
-               }
-
-               public static EventWaitHandle OpenExisting (string name)
-               {
-                       return(OpenExisting (name, EventWaitHandleRights.Synchronize | EventWaitHandleRights.Modify));
-               }
-
-               public static EventWaitHandle OpenExisting (string name, EventWaitHandleRights rights)
-               {
-                       if (name == null) {
-                               throw new ArgumentNullException ("name");
-                       }
-                       if ((name.Length == 0) ||
-                           (name.Length > 260)) {
-                               throw new ArgumentException ("name", Locale.GetText ("Invalid length [1-260]."));
-                       }
-                       
-                       MonoIOError error;
-                       IntPtr handle = NativeEventCalls.OpenEvent_internal (name, rights, out error);
-                       if (handle == (IntPtr)null) {
-                               if (error == MonoIOError.ERROR_FILE_NOT_FOUND) {
-                                       throw new WaitHandleCannotBeOpenedException (Locale.GetText ("Named Event handle does not exist: ") + name);
-                               } else if (error == MonoIOError.ERROR_ACCESS_DENIED) {
-                                       throw new UnauthorizedAccessException ();
-                               } else {
-                                       throw new IOException (Locale.GetText ("Win32 IO error: ") + error.ToString ());
-                               }
-                       }
-                       
-                       return(new EventWaitHandle (handle));
-               }
-
-               public static bool TryOpenExisting (string name, out EventWaitHandle result)
-               {
-                       return TryOpenExisting (
-                               name, EventWaitHandleRights.Synchronize | EventWaitHandleRights.Modify, out result);
-               }
-
-               public static bool TryOpenExisting (string name, EventWaitHandleRights rights,
-                                                   out EventWaitHandle result)
-               {
-                       if (name == null) {
-                               throw new ArgumentNullException ("name");
-                       }
-                       if ((name.Length == 0) || (name.Length > 260)) {
-                               throw new ArgumentException ("name", Locale.GetText ("Invalid length [1-260]."));
-                       }
-                       
-                       MonoIOError error;
-                       IntPtr handle = NativeEventCalls.OpenEvent_internal (name, rights, out error);
-                       if (handle == (IntPtr)null) {
-                               result = null;
-                               return false;
-                       }
-
-                       result = new EventWaitHandle (handle);
-                       return true;
-               }
-#else
-               public EventWaitHandle (bool initialState, EventResetMode mode, string name)
-               {
-                       throw new NotSupportedException ();
-               }
-               
-               public EventWaitHandle (bool initialState, EventResetMode mode,
-                                       string name, out bool createdNew)
-               {
-                       throw new NotSupportedException ();
-               }
-               
-               
-               public EventWaitHandle (bool initialState, EventResetMode mode,
-                                       string name, out bool createdNew,
-                                       EventWaitHandleSecurity eventSecurity)
-               {
-                       throw new NotSupportedException ();
-               }
-
-               public static EventWaitHandle OpenExisting (string name)
-               {
-                       throw new NotSupportedException (); 
-               }
-
-               public static EventWaitHandle OpenExisting (string name, EventWaitHandleRights rights)
-               {
-                       throw new NotSupportedException (); 
-               }
-
-               public static bool TryOpenExisting (string name, out EventWaitHandle result)
-               {
-                       throw new NotSupportedException (); 
-               }
-
-               public static bool TryOpenExisting (string name, EventWaitHandleRights rights,
-                                                   out EventWaitHandle result)
-               {
-                       throw new NotSupportedException (); 
-               }
-#endif
-
-               public bool Reset ()
-               {
-                       /* This needs locking since another thread could dispose the handle */
-                       lock (this) {
-                               CheckDisposed ();
-                       
-                               return NativeEventCalls.ResetEvent (SafeWaitHandle);
-                       }
-               }
-               
-               public bool Set ()
-               {
-                       lock (this) {
-                               CheckDisposed ();
-                       
-                               return NativeEventCalls.SetEvent (SafeWaitHandle);
-                       }
-               }
-
-               internal void CheckDisposed ()
-               {
-                       if (disposed)
-                               throw new ObjectDisposedException (GetType ().FullName);
-               }
-
-               bool disposed;
-               protected override void Dispose(bool explicitDisposing)
-               {
-                       base.Dispose (explicitDisposing);
-                       disposed = true;
-               }
-
-#if !MOBILE
-               public void SetAccessControl (EventWaitHandleSecurity eventSecurity)
-               {
-                       if (null == eventSecurity)
-                               throw new ArgumentNullException ("eventSecurity");
-                               
-                       eventSecurity.PersistModifications (SafeWaitHandle);
-
-               }
-#endif
-       }
-}
index b0320579bfa227ec3a8058fe50ab22774d6fbf6d..fc5a9f59babe887360a7eccdc6eadb088e285946 100644 (file)
@@ -45,7 +45,7 @@ namespace System.Threading
        internal static class NativeEventCalls
        {
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public static extern IntPtr CreateEvent_internal(bool manual,bool initial,string name, out bool created);
+               public static extern IntPtr CreateEvent_internal (bool manual, bool initial, string name, out int errorCode);
 
                public static bool SetEvent (SafeWaitHandle handle)
                {
@@ -82,7 +82,7 @@ namespace System.Threading
 
 #if !MOBILE
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public static extern IntPtr OpenEvent_internal (string name, EventWaitHandleRights rights, out MonoIOError error);
+               public static extern IntPtr OpenEvent_internal (string name, EventWaitHandleRights rights, out int errorCode);
 #endif
        }
 }
index d46999b767b535c04572e9cf6008f2d6fcdee221..f3bec17722a2b9a496d06907a9358fddbcb3957e 100644 (file)
@@ -65,7 +65,6 @@ namespace System.Threading {
                /* start_notify is used by the runtime to signal that Start()
                 * is ok to return
                 */
-               private IntPtr start_notify;
                private IntPtr stack_ptr;
                private UIntPtr static_data; /* GC-tracked */
                private IntPtr runtime_thread_info;
@@ -90,6 +89,7 @@ namespace System.Threading {
                private IntPtr interrupt_on_stop;
                private IntPtr flags;
                private IntPtr thread_pinning_ref;
+               private IntPtr abort_protected_block_count;
                /* 
                 * These fields are used to avoid having to increment corlib versions
                 * when a new field is added to the unmanaged MonoThread structure.
@@ -122,10 +122,6 @@ namespace System.Threading {
 
                IPrincipal principal;
                int principal_version;
-               bool current_culture_set;
-               bool current_ui_culture_set;
-               CultureInfo current_culture;
-               CultureInfo current_ui_culture;
 
                // the name of current_thread is
                // important because they are used by the runtime.
@@ -133,9 +129,6 @@ namespace System.Threading {
                [ThreadStatic]
                static Thread current_thread;
 
-               static internal CultureInfo default_culture;
-               static internal CultureInfo default_ui_culture;
-
                // can be both a ThreadStart and a ParameterizedThreadStart
                private MulticastDelegate m_Delegate;
 
@@ -340,54 +333,6 @@ namespace System.Threading {
                        }
                }
 
-               //[MethodImplAttribute (MethodImplOptions.InternalCall)]
-               //private static extern int current_lcid ();
-
-               public CultureInfo CurrentCulture {
-                       get {
-                               CultureInfo culture = current_culture;
-                               if (current_culture_set && culture != null)
-                                       return culture;
-
-                               if (default_culture != null)
-                                       return default_culture;
-
-                               current_culture = culture = CultureInfo.ConstructCurrentCulture ();
-                               return culture;
-                       }
-                       
-                       [SecurityPermission (SecurityAction.Demand, ControlThread=true)]
-                       set {
-                               if (value == null)
-                                       throw new ArgumentNullException ("value");
-
-                               value.CheckNeutral ();
-                               current_culture = value;
-                               current_culture_set = true;
-                       }
-               }
-
-               public CultureInfo CurrentUICulture {
-                       get {
-                               CultureInfo culture = current_ui_culture;
-                               if (current_ui_culture_set && culture != null)
-                                       return culture;
-
-                               if (default_ui_culture != null)
-                                       return default_ui_culture;
-
-                               current_ui_culture = culture = CultureInfo.ConstructCurrentUICulture ();
-                               return culture;
-                       }
-                       
-                       set {
-                               if (value == null)
-                                       throw new ArgumentNullException ("value");
-                               current_ui_culture = value;
-                               current_ui_culture_set = true;
-                       }
-               }
-
                public bool IsThreadPoolThread {
                        get {
                                return IsThreadPoolThreadInternal;
@@ -723,11 +668,6 @@ namespace System.Threading {
                        return ManagedThreadId;
                }
 
-               internal CultureInfo GetCurrentUICultureNoAppX ()
-               {
-                       return CultureInfo.CurrentUICulture;
-               }
-
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                internal static extern void GetStackTraces (out Thread[] threads, out object[] stack_frames);
 
index c1865f34bd366939da81af189dc94ab10a203ce4..ded3fb527c1a0825806bfa3e3b40cf2f139b9190 100644 (file)
@@ -36,6 +36,7 @@ using System.IO;
 using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 using System.Security;
+using System.Security.Permissions;
 using System.Runtime.Serialization.Formatters.Binary;
 
 using System.Runtime.Hosting;
@@ -139,12 +140,27 @@ namespace System
                                appBase = appBase.Substring (7);
                                if (Path.DirectorySeparatorChar != '/')
                                        appBase = appBase.Replace ('/', Path.DirectorySeparatorChar);
-                               if (Environment.IsRunningOnWindows) {
-                                       // Under Windows prepend "//" to indicate it's a local file
-                                       appBase = "//" + appBase;
+                       }
+                       appBase = Path.GetFullPath (appBase);
+
+                       if (Path.DirectorySeparatorChar != '/') {
+                               bool isExtendedPath = appBase.StartsWith (@"\\?\", StringComparison.Ordinal);
+                               if (appBase.IndexOf (':', isExtendedPath ? 6 : 2) != -1) {
+                                       throw new NotSupportedException ("The given path's format is not supported.");
                                }
-                       } else {
-                               appBase = Path.GetFullPath (appBase);
+                       }
+
+                       // validate the path
+                       string dir = Path.GetDirectoryName (appBase);
+                       if ((dir != null) && (dir.LastIndexOfAny (Path.GetInvalidPathChars ()) >= 0)) {
+                               string msg = String.Format (Locale.GetText ("Invalid path characters in path: '{0}'"), appBase);
+                               throw new ArgumentException (msg, "appBase");
+                       }
+
+                       string fname = Path.GetFileName (appBase);
+                       if ((fname != null) && (fname.LastIndexOfAny (Path.GetInvalidFileNameChars ()) >= 0)) {
+                               string msg = String.Format (Locale.GetText ("Invalid filename characters in path: '{0}'"), appBase);
+                               throw new ArgumentException (msg, "appBase");
                        }
 
                        return appBase;
index 4bd15db01a2c535a10bb7e634bca7c9d8ce52fd6..bbe43954a3b0f5d452c4f0eab50dce08280871ed 100644 (file)
@@ -57,7 +57,7 @@ namespace System {
                 * of icalls, do not require an increment.
                 */
 #pragma warning disable 169
-               private const int mono_corlib_version = 152;
+               private const int mono_corlib_version = 154;
 #pragma warning restore 169
 
                [ComVisible (true)]
@@ -472,7 +472,15 @@ namespace System {
                public extern static string[] GetCommandLineArgs ();
 
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               internal extern static string internalGetEnvironmentVariable (string variable);
+               internal extern static string internalGetEnvironmentVariable_native (IntPtr variable);
+
+               internal static string internalGetEnvironmentVariable (string variable) {
+                       if (variable == null)
+                               return null;
+                       using (var h = Mono.RuntimeMarshal.MarshalString (variable)) {
+                               return internalGetEnvironmentVariable_native (h.Value);
+                       }
+               }
 
                /// <summary>
                /// Return a string containing the value of the environment
@@ -862,6 +870,22 @@ namespace System {
                        }
                }
 #else
+               public static string GetEnvironmentVariable (string variable, EnvironmentVariableTarget target)
+               {
+                       if (target == EnvironmentVariableTarget.Process)
+                               return GetEnvironmentVariable (variable);
+
+                       return null;
+               }
+
+               public static IDictionary GetEnvironmentVariables (EnvironmentVariableTarget target)
+               {
+                       if (target == EnvironmentVariableTarget.Process)
+                               return GetEnvironmentVariables ();
+
+                       return (IDictionary)new Hashtable ();
+               }
+
                public static void SetEnvironmentVariable (string variable, string value)
                {
                        if (variable == null)
@@ -875,6 +899,14 @@ namespace System {
 
                        InternalSetEnvironmentVariable (variable, value);
                }
+
+               public static void SetEnvironmentVariable (string variable, string value, EnvironmentVariableTarget target)
+               {
+                       if (target == EnvironmentVariableTarget.Process)
+                               SetEnvironmentVariable (variable, value);
+
+                       // other targets ignored
+               }
 #endif
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                internal static extern void InternalSetEnvironmentVariable (string variable, string value);
@@ -893,7 +925,9 @@ namespace System {
                [SecurityCritical]
                public static void FailFast (string message, Exception exception)
                {
-                       throw new NotImplementedException ();
+#pragma warning disable 618
+                       throw new ExecutionEngineException (message, exception);
+#pragma warning restore
                }
 
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
index 1b070928c5505a05a65c0f699c220964226a6bb2..592f1d2f300adcf2d98d8c8712f1448ee240705d 100644 (file)
@@ -412,7 +412,14 @@ namespace System
 
                public static DateTime ConvertTimeBySystemTimeZoneId (DateTime dateTime, string sourceTimeZoneId, string destinationTimeZoneId)
                {
-                       return ConvertTime (dateTime, FindSystemTimeZoneById (sourceTimeZoneId), FindSystemTimeZoneById (destinationTimeZoneId));
+                       TimeZoneInfo source_tz;
+                       if (dateTime.Kind == DateTimeKind.Utc && sourceTimeZoneId == TimeZoneInfo.Utc.Id) {
+                               source_tz = Utc;
+                       } else {
+                               source_tz = FindSystemTimeZoneById (sourceTimeZoneId);
+                       }
+
+                       return ConvertTime (dateTime, source_tz, FindSystemTimeZoneById (destinationTimeZoneId));
                }
 
                public static DateTimeOffset ConvertTimeBySystemTimeZoneId (DateTimeOffset dateTimeOffset, string destinationTimeZoneId)
index 7479bc775b28da65130781710df3ce18d64e9e33..7054084409dab3c72f7be13a1ddc4df6b7c49d9f 100755 (executable)
@@ -679,6 +679,7 @@ namespace MonoTests.Microsoft.Win32
                                        subkey.Close ();
                                if (key != null)
                                        key.Close ();
+                               Registry.CurrentUser.DeleteSubKeyTree (subKeyName, false);
                        }
                }
 
@@ -699,6 +700,7 @@ namespace MonoTests.Microsoft.Win32
                                        subkey.Close ();
                                if (key != null)
                                        key.Close ();
+                               Registry.CurrentUser.DeleteSubKeyTree (subKeyName, false);
                        }
                }
 
@@ -708,14 +710,15 @@ namespace MonoTests.Microsoft.Win32
                        RegistryKey key = null;
                        RegistryKey key2 = null;
                        RegistryKey subkey = null;
-                       string subKeyName = "VolatileKey";
+                       string subKeyNameVolatile = "VolatileKey";
+                       string subKeyNameNonVolatile = "NonVolatileKey";
 
                        try {
                                // 
                                // Create a volatile key and try to open it as a normal one
                                //
-                               key = Registry.CurrentUser.CreateSubKey (subKeyName, RegistryKeyPermissionCheck.Default, RegistryOptions.Volatile);
-                               key2 = Registry.CurrentUser.CreateSubKey (subKeyName, RegistryKeyPermissionCheck.Default, RegistryOptions.None);
+                               key = Registry.CurrentUser.CreateSubKey (subKeyNameVolatile, RegistryKeyPermissionCheck.Default, RegistryOptions.Volatile);
+                               key2 = Registry.CurrentUser.CreateSubKey (subKeyNameVolatile, RegistryKeyPermissionCheck.Default, RegistryOptions.None);
                                Assert.AreEqual (key.Name, key2.Name, "A0");
 
                                subkey = key2.CreateSubKey ("Child", RegistryKeyPermissionCheck.Default, RegistryOptions.Volatile);
@@ -729,10 +732,9 @@ namespace MonoTests.Microsoft.Win32
                                // 
                                // Create a non-volatile key and try to open it as a volatile one
                                //
-                               subKeyName = "NonVolatileKey";
-                               key2 = Registry.CurrentUser.CreateSubKey (subKeyName, RegistryKeyPermissionCheck.Default, RegistryOptions.None);
+                               key2 = Registry.CurrentUser.CreateSubKey (subKeyNameNonVolatile, RegistryKeyPermissionCheck.Default, RegistryOptions.None);
                                key2.SetValue ("Name", "Mono");
-                               key = Registry.CurrentUser.CreateSubKey (subKeyName, RegistryKeyPermissionCheck.Default, RegistryOptions.Volatile);
+                               key = Registry.CurrentUser.CreateSubKey (subKeyNameNonVolatile, RegistryKeyPermissionCheck.Default, RegistryOptions.Volatile);
                                Assert.AreEqual (key.Name, key2.Name, "B0");
                                Assert.AreEqual ("Mono", key.GetValue ("Name"), "#B1");
                                Assert.AreEqual ("Mono", key2.GetValue ("Name"), "#B2");
@@ -746,7 +748,7 @@ namespace MonoTests.Microsoft.Win32
                                //
                                key.Close ();
                                key2.Close ();
-                               key = Registry.CurrentUser.CreateSubKey (subKeyName, RegistryKeyPermissionCheck.Default, RegistryOptions.Volatile);
+                               key = Registry.CurrentUser.CreateSubKey (subKeyNameNonVolatile, RegistryKeyPermissionCheck.Default, RegistryOptions.Volatile);
                                Assert.AreEqual ("Mono", key.GetValue ("Name"), "#C0");
                                Assert.AreEqual (true, key.OpenSubKey ("Child") != null, "#C1");
                        } finally {
@@ -756,6 +758,8 @@ namespace MonoTests.Microsoft.Win32
                                        key.Close ();
                                if (key2 != null)
                                        key2.Close ();
+                               Registry.CurrentUser.DeleteSubKeyTree (subKeyNameVolatile, false);
+                               Registry.CurrentUser.DeleteSubKeyTree (subKeyNameNonVolatile, false);
                        }
                }
 
index b5d78b7571eb7790a9669ef86e28fd90d39d942e..d347fb619657593e29a14d7aba9cd91ccd61aa8e 100644 (file)
@@ -53,7 +53,6 @@ namespace MonoTests.System.Collections.Generic
                        }
                }
 
-#if NET_4_5
                [Test]
                public void Create ()
                {
@@ -70,7 +69,6 @@ namespace MonoTests.System.Collections.Generic
                        } catch (ArgumentNullException) {
                        }
                }
-#endif
 
                [Test]
                public void DefaultComparer_UserComparable ()
index 364a8b3f955944c029f0cfa67784d550a1643701..73bfa734fa842390426dbbd1a8cc660c7bce12a7 100644 (file)
@@ -12,6 +12,7 @@ using System.Globalization;
 using System.IO;
 using System.Runtime.Serialization.Formatters.Binary;
 using System.Threading;
+using System.Threading.Tasks;
 
 using NUnit.Framework;
 
@@ -623,7 +624,6 @@ namespace MonoTests.System.Globalization
                        Assert.IsFalse (zh2.Equals (zh1), "#2");
                }
 
-#if NET_4_5
                CountdownEvent barrier = new CountdownEvent (3);
                AutoResetEvent[] evt = new AutoResetEvent [] { new AutoResetEvent (false), new AutoResetEvent (false), new AutoResetEvent (false), new AutoResetEvent (false)};
 
@@ -728,21 +728,37 @@ namespace MonoTests.System.Globalization
                }
 
                [Test]
-               public void DefaultThreadCurrentCultureAndNumberFormaters () {
+               public void DefaultThreadCurrentCultureIsIgnoredWhenCultureFlowsToThread ()
+               {
                        string us_str = null;
                        string br_str = null;
+
                        var thread = new Thread (() => {
                                CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
                                us_str = 100000.ToString ("C");
                                CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("pt-BR");
                                br_str = 100000.ToString ("C");
                        });
+
+                       var expected = 100000.ToString ("C");
+
                        thread.Start ();
-                       thread.Join ();
+                       Assert.IsTrue (thread.Join (5000), "#0");
                        CultureInfo.DefaultThreadCurrentCulture = null;
-                       Assert.AreEqual ("$100,000.00", us_str, "#1");
-                       Assert.AreEqual ("R$ 100.000,00", br_str, "#2");
+                       Assert.AreEqual (expected, us_str, "#1");
+                       Assert.AreEqual (expected, br_str, "#2");
+               }
+
+               [Test]
+               public void FlowCultureInfoFromParentThreadSinceNet46 ()
+               {
+                       Func<Task> f = async () => {
+                               Thread.CurrentThread.CurrentUICulture = new CultureInfo ("pt-BR");
+                               await Task.Yield ();
+                               Assert.AreEqual ("pt-BR", Thread.CurrentThread.CurrentUICulture.Name);
+                       };
+
+                       f ().Wait ();
                }
-#endif
        }
 }
index d6aacac5dc8ba3815d2c0c3e72b7200bf3249b69..34a431aabd715880e7c6962ead01cbeb150e68d2 100644 (file)
@@ -168,6 +168,8 @@ namespace MonoTests.System.IO
                                        info = new DirectoryInfo ("/test/");
                                        Assert.AreEqual ("test", info.Name, "#4");
                                } else {
+                                       Directory.SetCurrentDirectory (@"C:\");
+
                                        info = new DirectoryInfo (@"c:");
                                        Assert.AreEqual (@"C:\", info.Name, "#4");
 
@@ -217,6 +219,8 @@ namespace MonoTests.System.IO
                                        Assert.IsNotNull (info.Parent, "#7a");
                                        Assert.AreEqual ("/", info.Parent.FullName, "#7b");
                                } else {
+                                       Directory.SetCurrentDirectory (@"C:\");
+
                                        info = new DirectoryInfo (@"c:");
                                        Assert.IsNull (info.Parent, "#4");
 
@@ -418,6 +422,8 @@ namespace MonoTests.System.IO
                                di = new DirectoryInfo ("/test/");
                                Assert.AreEqual ("/test/", di.FullName, "#D4");
                        } else {
+                               Directory.SetCurrentDirectory (@"C:\");
+
                                di = new DirectoryInfo (@"c:");
                                Assert.AreEqual (@"C:\", di.FullName, "#D1");
 
index 50755fa0dc5bf4ac8b4ee615910d3872d75d1dd4..e4000ea33d81b2877940c9a4dcd3007d63dca7a9 100644 (file)
@@ -758,9 +758,9 @@ namespace MonoTests.System.IO
                                try {
                                        info.MoveTo (destFile);
                                        Assert.Fail ("#1");
-                               } catch (FileNotFoundException ex) {
+                               } catch (DirectoryNotFoundException ex) {
                                        // Could not find a part of the path
-                                       Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#2");
+                                       Assert.AreEqual (typeof (DirectoryNotFoundException), ex.GetType (), "#2");
                                        Assert.IsNull (ex.InnerException, "#3");
                                        Assert.IsNotNull (ex.Message, "#4");
                                }
index 008930061e45c2c6edc9b06b9cce89f4c976a6e7..b07955903f41a1946e709d8568c1fa42c8c02529 100644 (file)
@@ -25,10 +25,6 @@ namespace MonoTests.System.IO
        {
                string TempFolder = Path.Combine (Path.GetTempPath (), "MonoTests.System.IO.Tests");
                static readonly char DSC = Path.DirectorySeparatorChar;
-               static bool MacOSX = false;
-
-               [DllImport ("libc")]
-               static extern int uname (IntPtr buf);
 
                [TearDown]
                public void TearDown ()
@@ -44,13 +40,6 @@ namespace MonoTests.System.IO
                                Directory.Delete (TempFolder, true);
 
                        Directory.CreateDirectory (TempFolder);
-#if !MOBILE                    
-                       // from XplatUI.cs
-                       IntPtr buf = Marshal.AllocHGlobal (8192);
-                       if (uname (buf) == 0)
-                               MacOSX = Marshal.PtrToStringAnsi (buf) == "Darwin";
-                       Marshal.FreeHGlobal (buf);
-#endif
                }
 
                public void TestCtr ()
index f552e933a65290eca43c3c6cd3ffa9df00148d7d..b7c472b4fdd8308a3f13fede8ce20f664ca38f6e 100644 (file)
@@ -17,9 +17,7 @@ using System.IO;
 using System.Runtime.Serialization.Formatters.Binary;
 using System.Text;
 using System.Threading;
-#if NET_4_5
 using System.Threading.Tasks;
-#endif
 
 using NUnit.Framework;
 
@@ -1119,7 +1117,6 @@ namespace MonoTests.System.IO
                        Assert.IsTrue (ms.DisposedCalled, "After");
                }
 
-#if NET_4_5
                [Test]
                public void ReadAsync ()
                {
@@ -1323,6 +1320,5 @@ namespace MonoTests.System.IO
                                return true;
                        }
                }
-#endif
        }
 }
index c3ab9935350c9b1f3071960bda46d06d97b74d81..7b83492b998c541237412e89f84535c6f479001b 100644 (file)
@@ -37,6 +37,7 @@ namespace MonoTests.System.IO
                static string path3;
                static OsType OS;
                static char DSC = Path.DirectorySeparatorChar;
+               static char ADSC = Path.AltDirectorySeparatorChar;
 
                [SetUp]
                public void SetUp ()
@@ -359,6 +360,12 @@ namespace MonoTests.System.IO
                        }
                }
 
+               [Test]
+               public void GetDirectoryName_Replaces_AltDirectorySeparatorChar ()
+               {
+                       Assert.AreEqual ($"foo{DSC}bar", Path.GetDirectoryName ($"foo{ADSC}bar{ADSC}dingus"), "#1");
+               }
+
                [Test]
                public void GetExtension ()
                {
index 54e5e04243583a489dff3547f3eb5d601d8d08fa..eb29cfa9e4b5f26aef1d9cc09feb0159f0396ba7 100644 (file)
@@ -9,9 +9,7 @@
 using System;
 using System.IO;
 using System.Text;
-#if NET_4_5
 using System.Threading.Tasks;
-#endif
 
 using NUnit.Framework;
 
@@ -845,7 +843,6 @@ public class StreamReaderTest
                Assert.AreEqual (0, StreamReader.Null.ReadBlock (buffer, 0, buffer.Length));
        }
 
-#if NET_4_5
        [Test]
        public void ReadLineAsync ()
        {
@@ -866,7 +863,6 @@ public class StreamReaderTest
                Assert.IsTrue (result.Wait (3000), "#1");
                Assert.AreEqual ("ab" + Environment.NewLine, result.Result);
        }
-#endif
 }
 
 class MyStream : Stream {
index e22a13736fd5c021a20570dea5c1ee1ab9a29486..a7ad4ea65e45d0a83d65324cf3895bd1209a6fa0 100644 (file)
@@ -120,7 +120,6 @@ namespace MonoTests.System.IO
                        Assert.IsFalse (s.CanRead, "#1");
                }
 
-#if NET_4_5
                [Test]
                public void CopyAsync ()
                {
@@ -211,6 +210,5 @@ namespace MonoTests.System.IO
                        } catch (AggregateException) {
                        }
                }
-#endif
        }
 }
index 661cffc18c61370723ed9b5137ce483534128833..a0afe231788c15e8fe1d95f9dbdf8e0681e60223 100644 (file)
@@ -1051,7 +1051,6 @@ namespace MonoTests.System.IO
                Assert.AreEqual (5, ms.Position, "#2");
        }
 
-#if NET_4_5
        [Test]
        public void FlushAsync ()
        {
@@ -1098,7 +1097,6 @@ namespace MonoTests.System.IO
                Assert.IsTrue (t.Wait (1000), "#5");
        }
 
-#endif
 
        // TODO - Write - test errors, functionality tested in TestFlush.
 }
index 4d8f1bf0ddace880834887a756e0b5f4aea2b91a..b707567f1de9e8bae42dce2492e7df4b572f5908 100644 (file)
@@ -1152,10 +1152,8 @@ public class AssemblyNameTest {
                Assert.IsNull (an.GetPublicKey (), "GetPublicKey");
                Assert.IsNull (an.GetPublicKeyToken (), "GetPublicKeyToken");
                Assert.AreEqual ("TestAssembly", an.ToString (), "ToString");
-#if NET_4_5
                Assert.IsNull (an.CultureName, "CultureName");
                Assert.AreEqual (AssemblyContentType.Default, an.ContentType, "ContentType");
-#endif
        }
 
        [Test] // ctor (String)
index bc3416441cfad03b93e428301df40573aaff264e..e82d81fba6185798f6112b86a0afa64a57a67b96 100644 (file)
@@ -55,14 +55,27 @@ namespace MonoTests.System.Reflection
        [TestFixture]
        public class AssemblyTest
        {
-               static string TempFolder = Path.Combine (Path.GetTempPath (),
+               static string BaseTempFolder = Path.Combine (Path.GetTempPath (),
                        "MonoTests.System.Reflection.AssemblyTest");
+               static string TempFolder;
+
+               [TestFixtureSetUp]
+               public void FixtureSetUp ()
+               {
+                       try {
+                               // Try to cleanup from any previous NUnit run.
+                               Directory.Delete (BaseTempFolder, true);
+                       } catch (Exception) {
+                       }
+               }
 
                [SetUp]
                public void SetUp ()
                {
-                       while (Directory.Exists (TempFolder))
-                               TempFolder = Path.Combine (TempFolder, "2");
+                       int i = 0;
+                       do {
+                               TempFolder = Path.Combine (BaseTempFolder, (++i).ToString());
+                       } while (Directory.Exists (TempFolder));
                        Directory.CreateDirectory (TempFolder);
                }
 
@@ -70,8 +83,8 @@ namespace MonoTests.System.Reflection
                public void TearDown ()
                {
                        try {
-                               // This throws an exception under MS.NET, since the directory contains loaded
-                               // assemblies.
+                               // This throws an exception under MS.NET and Mono on Windows,
+                               // since the directory contains loaded assemblies.
                                Directory.Delete (TempFolder, true);
                        } catch (Exception) {
                        }
@@ -410,22 +423,21 @@ namespace MonoTests.System.Reflection
                [Test] // bug #78517
                public void LoadFrom_Empty_Assembly ()
                {
-                       string tempFile = Path.GetTempFileName ();
+                       string tempFile = Path.Combine (TempFolder, Path.GetRandomFileName ());
+                       File.CreateText (tempFile).Close ();
 
                        try {
                                Assembly.LoadFrom (tempFile);
                                Assert.Fail ("#1");
                        } catch (BadImageFormatException ex) {
                                Assert.IsNull (ex.InnerException, "#2");
-                       } finally {
-                               File.Delete (tempFile);
                        }
                }
 
                [Test] // bug #78517
                public void LoadFrom_Invalid_Assembly ()
                {
-                       string tempFile = Path.GetTempFileName ();
+                       string tempFile = Path.Combine (TempFolder, Path.GetRandomFileName ());
                        using (StreamWriter sw = File.CreateText (tempFile)) {
                                sw.WriteLine ("foo");
                                sw.Close ();
@@ -436,24 +448,19 @@ namespace MonoTests.System.Reflection
                                Assert.Fail ("#1");
                        } catch (BadImageFormatException ex) {
                                Assert.IsNull (ex.InnerException, "#2");
-                       } finally {
-                               File.Delete (tempFile);
                        }
                }
 
                [Test]
                public void LoadFrom_NonExisting_Assembly ()
                {
-                       string tempFile = Path.GetTempFileName ();
-                       File.Delete (tempFile);
+                       string tempFile = Path.Combine (TempFolder, Path.GetRandomFileName ());
 
                        try {
                                Assembly.LoadFrom (tempFile);
                                Assert.Fail ("#1");
                        } catch (FileNotFoundException ex) {
                                Assert.IsNull (ex.InnerException, "#2");
-                       } finally {
-                               File.Delete (tempFile);
                        }
                }
 
@@ -520,28 +527,24 @@ namespace MonoTests.System.Reflection
                [Test]
                public void Location_Empty() {
                        string assemblyFileName = Path.Combine (
-                               Path.GetTempPath (), "AssemblyLocation.dll");
-
-                       try {
-                               AssemblyName assemblyName = new AssemblyName ();
-                               assemblyName.Name = "AssemblyLocation";
-
-                               AssemblyBuilder ab = AppDomain.CurrentDomain
-                                       .DefineDynamicAssembly (assemblyName,
-                                       AssemblyBuilderAccess.Save,
-                                       Path.GetTempPath (),
-                                       AppDomain.CurrentDomain.Evidence);
-                               ab.Save (Path.GetFileName (assemblyFileName));
-
-                               using (FileStream fs = File.OpenRead (assemblyFileName)) {
-                                       byte[] buffer = new byte[fs.Length];
-                                       fs.Read (buffer, 0, buffer.Length);
-                                       Assembly assembly = Assembly.Load (buffer);
-                                       Assert.AreEqual (string.Empty, assembly.Location);
-                                       fs.Close ();
-                               }
-                       } finally {
-                               File.Delete (assemblyFileName);
+                               TempFolder, "AssemblyLocation.dll");
+
+                       AssemblyName assemblyName = new AssemblyName ();
+                       assemblyName.Name = "AssemblyLocation";
+
+                       AssemblyBuilder ab = AppDomain.CurrentDomain
+                               .DefineDynamicAssembly (assemblyName,
+                               AssemblyBuilderAccess.Save,
+                               TempFolder,
+                               AppDomain.CurrentDomain.Evidence);
+                       ab.Save (Path.GetFileName (assemblyFileName));
+
+                       using (FileStream fs = File.OpenRead (assemblyFileName)) {
+                               byte[] buffer = new byte[fs.Length];
+                               fs.Read (buffer, 0, buffer.Length);
+                               Assembly assembly = Assembly.Load (buffer);
+                               Assert.AreEqual (string.Empty, assembly.Location);
+                               fs.Close ();
                        }
                }
 
@@ -549,56 +552,52 @@ namespace MonoTests.System.Reflection
                public void SateliteAssemblyForInMemoryAssembly ()
                {
                        string assemblyFileName = Path.Combine (
-                               Path.GetTempPath (), "AssemblyLocation1.dll");
+                               TempFolder, "AssemblyLocation1.dll");
 
-                       try {
-                               AssemblyName assemblyName = new AssemblyName ();
-                               assemblyName.Name = "AssemblyLocation1";
-
-                               AssemblyBuilder ab = AppDomain.CurrentDomain
-                                       .DefineDynamicAssembly (assemblyName,
-                                               AssemblyBuilderAccess.Save,
-                                               Path.GetTempPath ());
+                       AssemblyName assemblyName = new AssemblyName ();
+                       assemblyName.Name = "AssemblyLocation1";
 
-                               ModuleBuilder moduleBuilder = ab.DefineDynamicModule (assemblyName.Name, assemblyName.Name + ".dll");
-                               TypeBuilder typeBuilder = moduleBuilder.DefineType ("Program", TypeAttributes.Public);
+                       AssemblyBuilder ab = AppDomain.CurrentDomain
+                               .DefineDynamicAssembly (assemblyName,
+                                       AssemblyBuilderAccess.Save,
+                                       TempFolder);
 
-                               MethodBuilder methodBuilder = typeBuilder.DefineMethod ("TestCall", MethodAttributes.Public | MethodAttributes.Static, typeof(void), Type.EmptyTypes);
-                               ILGenerator gen = methodBuilder.GetILGenerator ();
+                       ModuleBuilder moduleBuilder = ab.DefineDynamicModule (assemblyName.Name, assemblyName.Name + ".dll");
+                       TypeBuilder typeBuilder = moduleBuilder.DefineType ("Program", TypeAttributes.Public);
 
-                               //
-                               //      var resourceManager = new ResourceManager (typeof (Program));
-                               //      resourceManager.GetString ("test");
-                               //
-                               gen.Emit (OpCodes.Ldtoken, typeBuilder);
-                               gen.Emit (OpCodes.Call, typeof(Type).GetMethod ("GetTypeFromHandle"));
-                               gen.Emit (OpCodes.Newobj, typeof(ResourceManager).GetConstructor (new Type[] { typeof(Type) }));
-                               gen.Emit (OpCodes.Ldstr, "test");
-                               gen.Emit (OpCodes.Callvirt, typeof(ResourceManager).GetMethod ("GetString", new Type[] { typeof(string) }));
-                               gen.Emit (OpCodes.Pop);
-                               gen.Emit (OpCodes.Ret);
+                       MethodBuilder methodBuilder = typeBuilder.DefineMethod ("TestCall", MethodAttributes.Public | MethodAttributes.Static, typeof(void), Type.EmptyTypes);
+                       ILGenerator gen = methodBuilder.GetILGenerator ();
 
-                               typeBuilder.CreateType ();
+                       //
+                       //      var resourceManager = new ResourceManager (typeof (Program));
+                       //      resourceManager.GetString ("test");
+                       //
+                       gen.Emit (OpCodes.Ldtoken, typeBuilder);
+                       gen.Emit (OpCodes.Call, typeof(Type).GetMethod ("GetTypeFromHandle"));
+                       gen.Emit (OpCodes.Newobj, typeof(ResourceManager).GetConstructor (new Type[] { typeof(Type) }));
+                       gen.Emit (OpCodes.Ldstr, "test");
+                       gen.Emit (OpCodes.Callvirt, typeof(ResourceManager).GetMethod ("GetString", new Type[] { typeof(string) }));
+                       gen.Emit (OpCodes.Pop);
+                       gen.Emit (OpCodes.Ret);
 
-                               ab.Save (Path.GetFileName (assemblyFileName));
+                       typeBuilder.CreateType ();
 
-                               using (FileStream fs = File.OpenRead (assemblyFileName)) {
-                                       byte[] buffer = new byte[fs.Length];
-                                       fs.Read (buffer, 0, buffer.Length);
-                                       Assembly assembly = Assembly.Load (buffer);
+                       ab.Save (Path.GetFileName (assemblyFileName));
 
-                                       var mm = assembly.GetType ("Program").GetMethod ("TestCall");
-                                       try {
-                                               mm.Invoke (null, null);
-                                               Assert.Fail ();
-                                       } catch (TargetInvocationException e) {
-                                               Assert.IsTrue (e.InnerException is MissingManifestResourceException);
-                                       }
+                       using (FileStream fs = File.OpenRead (assemblyFileName)) {
+                               byte[] buffer = new byte[fs.Length];
+                               fs.Read (buffer, 0, buffer.Length);
+                               Assembly assembly = Assembly.Load (buffer);
 
-                                       fs.Close ();
+                               var mm = assembly.GetType ("Program").GetMethod ("TestCall");
+                               try {
+                                       mm.Invoke (null, null);
+                                       Assert.Fail ();
+                               } catch (TargetInvocationException e) {
+                                       Assert.IsTrue (e.InnerException is MissingManifestResourceException);
                                }
-                       } finally {
-                               File.Delete (assemblyFileName);
+
+                               fs.Close ();
                        }
                }
 
@@ -607,19 +606,15 @@ namespace MonoTests.System.Reflection
                public void bug78464 ()
                {
                        string assemblyFileName = Path.Combine (
-                               Path.GetTempPath (), "bug78464.dll");
+                               TempFolder, "bug78464.dll");
 
+                       // execute test in separate appdomain to allow assembly to be unloaded
+                       AppDomain testDomain = CreateTestDomain (AppDomain.CurrentDomain.BaseDirectory, false);
+                       CrossDomainTester crossDomainTester = CreateCrossDomainTester (testDomain);
                        try {
-                               // execute test in separate appdomain to allow assembly to be unloaded
-                               AppDomain testDomain = CreateTestDomain (AppDomain.CurrentDomain.BaseDirectory, false);
-                               CrossDomainTester crossDomainTester = CreateCrossDomainTester (testDomain);
-                               try {
-                                       crossDomainTester.bug78464 (assemblyFileName);
-                               } finally {
-                                       AppDomain.Unload (testDomain);
-                               }
+                               crossDomainTester.bug78464 (assemblyFileName);
                        } finally {
-                               File.Delete (assemblyFileName);
+                               AppDomain.Unload (testDomain);
                        }
                }
 
@@ -628,36 +623,32 @@ namespace MonoTests.System.Reflection
                public void bug78465 ()
                {
                        string assemblyFileName = Path.Combine (
-                               Path.GetTempPath (), "bug78465.dll");
+                               TempFolder, "bug78465.dll");
+
+                       AssemblyName assemblyName = new AssemblyName ();
+                       assemblyName.Name = "bug78465";
+
+                       AssemblyBuilder ab = AppDomain.CurrentDomain
+                               .DefineDynamicAssembly (assemblyName,
+                               AssemblyBuilderAccess.Save,
+                               Path.GetDirectoryName (assemblyFileName),
+                               AppDomain.CurrentDomain.Evidence);
+                       ab.Save (Path.GetFileName (assemblyFileName));
+
+                       using (FileStream fs = File.OpenRead (assemblyFileName)) {
+                               byte[] buffer = new byte[fs.Length];
+                               fs.Read (buffer, 0, buffer.Length);
+                               Assembly assembly = Assembly.Load (buffer);
+                               Assert.AreEqual (string.Empty, assembly.Location, "#1");
+                               fs.Close ();
+                       }
 
+                       AppDomain testDomain = CreateTestDomain (AppDomain.CurrentDomain.BaseDirectory, false);
+                       CrossDomainTester crossDomainTester = CreateCrossDomainTester (testDomain);
                        try {
-                               AssemblyName assemblyName = new AssemblyName ();
-                               assemblyName.Name = "bug78465";
-
-                               AssemblyBuilder ab = AppDomain.CurrentDomain
-                                       .DefineDynamicAssembly (assemblyName,
-                                       AssemblyBuilderAccess.Save,
-                                       Path.GetDirectoryName (assemblyFileName),
-                                       AppDomain.CurrentDomain.Evidence);
-                               ab.Save (Path.GetFileName (assemblyFileName));
-
-                               using (FileStream fs = File.OpenRead (assemblyFileName)) {
-                                       byte[] buffer = new byte[fs.Length];
-                                       fs.Read (buffer, 0, buffer.Length);
-                                       Assembly assembly = Assembly.Load (buffer);
-                                       Assert.AreEqual (string.Empty, assembly.Location, "#1");
-                                       fs.Close ();
-                               }
-
-                               AppDomain testDomain = CreateTestDomain (AppDomain.CurrentDomain.BaseDirectory, false);
-                               CrossDomainTester crossDomainTester = CreateCrossDomainTester (testDomain);
-                               try {
-                                       crossDomainTester.bug78465 (assemblyFileName);
-                               } finally {
-                                       AppDomain.Unload (testDomain);
-                               }
+                               crossDomainTester.bug78465 (assemblyFileName);
                        } finally {
-                               File.Delete (assemblyFileName);
+                               AppDomain.Unload (testDomain);
                        }
                }
 
@@ -665,9 +656,9 @@ namespace MonoTests.System.Reflection
                [Category("MobileNotWorking")]
                public void bug78468 ()
                {
-                       string assemblyFileNameA = Path.Combine (Path.GetTempPath (),
+                       string assemblyFileNameA = Path.Combine (TempFolder,
                                "bug78468a.dll");
-                       string resourceFileName = Path.Combine (Path.GetTempPath (),
+                       string resourceFileName = Path.Combine (TempFolder,
                                "readme.txt");
 
                        using (StreamWriter sw = File.CreateText (resourceFileName)) {
@@ -675,62 +666,56 @@ namespace MonoTests.System.Reflection
                                sw.Close ();
                        }
 
-                       try {
-                               AssemblyName assemblyName = new AssemblyName ();
-                               assemblyName.Name = "bug78468a";
+                       AssemblyName assemblyName = new AssemblyName ();
+                       assemblyName.Name = "bug78468a";
 
-                               AssemblyBuilder ab = AppDomain.CurrentDomain
-                                       .DefineDynamicAssembly (assemblyName,
-                                       AssemblyBuilderAccess.Save,
-                                       Path.GetTempPath (),
-                                       AppDomain.CurrentDomain.Evidence);
-                               ab.AddResourceFile ("read", "readme.txt");
-                               ab.Save (Path.GetFileName (assemblyFileNameA));
+                       AssemblyBuilder ab = AppDomain.CurrentDomain
+                               .DefineDynamicAssembly (assemblyName,
+                               AssemblyBuilderAccess.Save,
+                               TempFolder,
+                               AppDomain.CurrentDomain.Evidence);
+                       ab.AddResourceFile ("read", "readme.txt");
+                       ab.Save (Path.GetFileName (assemblyFileNameA));
 
-                               Assembly assembly;
+                       Assembly assembly;
 
-                               using (FileStream fs = File.OpenRead (assemblyFileNameA)) {
-                                       byte[] buffer = new byte[fs.Length];
-                                       fs.Read (buffer, 0, buffer.Length);
-                                       assembly = Assembly.Load (buffer);
-                                       fs.Close ();
-                               }
+                       using (FileStream fs = File.OpenRead (assemblyFileNameA)) {
+                               byte[] buffer = new byte[fs.Length];
+                               fs.Read (buffer, 0, buffer.Length);
+                               assembly = Assembly.Load (buffer);
+                               fs.Close ();
+                       }
 
-                               Assert.AreEqual (string.Empty, assembly.Location, "#A1");
-                               string[] resNames = assembly.GetManifestResourceNames ();
-                               Assert.IsNotNull (resNames, "#A2");
-                               Assert.AreEqual (1, resNames.Length, "#A3");
-                               Assert.AreEqual ("read", resNames[0], "#A4");
-                               ManifestResourceInfo resInfo = assembly.GetManifestResourceInfo ("read");
-                               Assert.IsNotNull (resInfo, "#A5");
-                               Assert.AreEqual ("readme.txt", resInfo.FileName, "#A6");
-                               Assert.IsNull (resInfo.ReferencedAssembly, "#A7");
-                               Assert.AreEqual ((ResourceLocation) 0, resInfo.ResourceLocation, "#A8");
-                               try {
-                                       assembly.GetManifestResourceStream ("read");
-                                       Assert.Fail ("#A9");
-                               } catch (FileNotFoundException) {
-                               }
-                               try {
-                                       assembly.GetFile ("readme.txt");
-                                       Assert.Fail ("#A10");
-                               } catch (FileNotFoundException) {
-                               }
+                       Assert.AreEqual (string.Empty, assembly.Location, "#A1");
+                       string[] resNames = assembly.GetManifestResourceNames ();
+                       Assert.IsNotNull (resNames, "#A2");
+                       Assert.AreEqual (1, resNames.Length, "#A3");
+                       Assert.AreEqual ("read", resNames[0], "#A4");
+                       ManifestResourceInfo resInfo = assembly.GetManifestResourceInfo ("read");
+                       Assert.IsNotNull (resInfo, "#A5");
+                       Assert.AreEqual ("readme.txt", resInfo.FileName, "#A6");
+                       Assert.IsNull (resInfo.ReferencedAssembly, "#A7");
+                       Assert.AreEqual ((ResourceLocation) 0, resInfo.ResourceLocation, "#A8");
+                       try {
+                               assembly.GetManifestResourceStream ("read");
+                               Assert.Fail ("#A9");
+                       } catch (FileNotFoundException) {
+                       }
+                       try {
+                               assembly.GetFile ("readme.txt");
+                               Assert.Fail ("#A10");
+                       } catch (FileNotFoundException) {
+                       }
 
-                               string assemblyFileNameB = Path.Combine (Path.GetTempPath (),
-                                       "bug78468b.dll");
+                       string assemblyFileNameB = Path.Combine (TempFolder,
+                               "bug78468b.dll");
 
-                               AppDomain testDomain = CreateTestDomain (AppDomain.CurrentDomain.BaseDirectory, false);
-                               CrossDomainTester crossDomainTester = CreateCrossDomainTester (testDomain);
-                               try {
-                                       crossDomainTester.bug78468 (assemblyFileNameB);
-                               } finally {
-                                       AppDomain.Unload (testDomain);
-                                       File.Delete (assemblyFileNameB);
-                               }
+                       AppDomain testDomain = CreateTestDomain (AppDomain.CurrentDomain.BaseDirectory, false);
+                       CrossDomainTester crossDomainTester = CreateCrossDomainTester (testDomain);
+                       try {
+                               crossDomainTester.bug78468 (assemblyFileNameB);
                        } finally {
-                               File.Delete (assemblyFileNameA);
-                               File.Delete (resourceFileName);
+                               AppDomain.Unload (testDomain);
                        }
                }
 
@@ -768,8 +753,7 @@ namespace MonoTests.System.Reflection
                [Category ("NotWorking")] // patch for bug #79720 must be committed first
                public void Load_Culture ()
                {
-                       string tempDir = Path.Combine (Path.GetTempPath (),
-                               "MonoTests.System.Reflection.AssemblyTest");
+                       string tempDir = TempFolder;
                        string cultureTempDir = Path.Combine (tempDir, "nl-BE");
                        if (!Directory.Exists (cultureTempDir))
                                Directory.CreateDirectory (cultureTempDir);
@@ -866,8 +850,6 @@ namespace MonoTests.System.Reflection
                                Assert.IsTrue (cdt.AssertFileNotFoundException (aname), "#D3");
                        } finally {
                                AppDomain.Unload (ad);
-                               if (Directory.Exists (tempDir))
-                                       Directory.Delete (tempDir, true);
                        }
                }
 
@@ -875,8 +857,7 @@ namespace MonoTests.System.Reflection
                [Category ("NotWorking")] // in non-default domain, MS throws FileNotFoundException
                public void Load_Culture_Mismatch ()
                {
-                       string tempDir = Path.Combine (Path.GetTempPath (),
-                               "MonoTests.System.Reflection.AssemblyTest");
+                       string tempDir = TempFolder;
                        string cultureTempDir = Path.Combine (tempDir, "en-US");
                        if (!Directory.Exists (cultureTempDir))
                                Directory.CreateDirectory (cultureTempDir);
@@ -910,8 +891,6 @@ namespace MonoTests.System.Reflection
                                Assert.IsTrue (cdt.AssertFileNotFoundException (aname), "#B1");
                        } finally {
                                AppDomain.Unload (ad);
-                               if (Directory.Exists (tempDir))
-                                       Directory.Delete (tempDir, true);
                        }
                }
 
@@ -920,10 +899,7 @@ namespace MonoTests.System.Reflection
                [Category("MobileNotWorking")]
                public void Load_PartialVersion ()
                {
-                       string tempDir = Path.Combine (Path.GetTempPath (),
-                               "MonoTests.System.Reflection.AssemblyTest");
-                       if (!Directory.Exists (tempDir))
-                               Directory.CreateDirectory (tempDir);
+                       string tempDir = TempFolder;
 
                        AppDomain ad = CreateTestDomain (tempDir, true);
                        try {
@@ -953,8 +929,6 @@ namespace MonoTests.System.Reflection
                                Assert.IsTrue (cdt.AssertLoad (aname.FullName), "#C2");
                        } finally {
                                AppDomain.Unload (ad);
-                               if (Directory.Exists (tempDir))
-                                       Directory.Delete (tempDir, true);
                        }
                }
 
@@ -1128,22 +1102,7 @@ namespace MonoTests.System.Reflection
                [Test]
                public void bug79872 ()
                {
-                       Random rnd = new Random ();
-                       string outdir;
-                       int tries = 0;
-
-               retry:
-                       outdir = Path.Combine (Path.GetTempPath (), "bug79872-" + rnd.Next (10000, 99999));
-                       if (Directory.Exists (outdir)) {
-                               try {
-                                       Directory.Delete (outdir, true);
-                               } catch {
-                                       if (++tries <= 100)
-                                               goto retry;
-                               }
-                       }
-
-                       Directory.CreateDirectory (outdir);
+                       string outdir = TempFolder;
 
                        AssemblyName an = new AssemblyName ();
                        an.Name = "bug79872";
@@ -1175,8 +1134,6 @@ namespace MonoTests.System.Reflection
                                // swallow the rest
                        }
                        Assert.IsTrue (ok, "Complain on loading a .NET metadata file without an assembly manifest");
-
-                       Directory.Delete (outdir, true);
                }
 #endif
 
@@ -1320,7 +1277,6 @@ namespace MonoTests.System.Reflection
                        Assert.AreEqual (GetType().Assembly, a);
                }
 
-#if NET_4_5
                [Test]
                public void DefinedTypes_Equality ()
                {
@@ -1329,7 +1285,6 @@ namespace MonoTests.System.Reflection
 
                        Assert.AreSame (x1, x2, "#1");
                }
-#endif
 
                class MyAssembly : Assembly { }
 
index f16d9a2a0f22a6ca28ef676adbd626e68253139b..a2d0f7cfac42b34be0fc3dad3f25bcb4a54afd87 100644 (file)
@@ -26,7 +26,6 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_4_5
 
 using System;
 using System.Reflection;
@@ -54,4 +53,3 @@ namespace MonoTests.System.Reflection
        }
 }
 
-#endif
\ No newline at end of file
index c93fecfa422ab43ebde24a1972bcf2900ddff0cd..d40ff368bc2c5faf56451a4e83e2f434a8ea49fd 100644 (file)
@@ -24,13 +24,26 @@ namespace MonoTests.System.Reflection
 [TestFixture]
 public class ModuleTest
 {
-       static string TempFolder = Path.Combine (Path.GetTempPath (), "MonoTests.System.Reflection.ModuleTest");
+       static string BaseTempFolder = Path.Combine (Path.GetTempPath (), "MonoTests.System.Reflection.ModuleTest");
+       static string TempFolder;
+
+       [TestFixtureSetUp]
+       public void FixtureSetUp ()
+       {
+               try {
+                       // Try to cleanup from any previous NUnit run.
+                       Directory.Delete (BaseTempFolder, true);
+               } catch (Exception) {
+               }
+       }
 
        [SetUp]
        public void SetUp ()
        {
-               while (Directory.Exists (TempFolder))
-                       TempFolder = Path.Combine (TempFolder, "2");
+               int i = 0;
+               do {
+                       TempFolder = Path.Combine (BaseTempFolder, (++i).ToString());
+               } while (Directory.Exists (TempFolder));
                Directory.CreateDirectory (TempFolder);
        }
 
@@ -38,8 +51,8 @@ public class ModuleTest
        public void TearDown ()
        {
                try {
-                       // This throws an exception under MS.NET, since the directory contains loaded
-                       // assemblies.
+                       // This throws an exception under MS.NET and Mono on Windows,
+                       // since the directory contains loaded assemblies.
                        Directory.Delete (TempFolder, true);
                } catch (Exception) {
                }
index 406b569c8d4245f3a43273294eab72e19425ecf5..fb2706d575b9753db0bc5597138d7baa07c910fb 100644 (file)
@@ -97,14 +97,12 @@ namespace MonoTests.System.Reflection
                        Assert.AreEqual (ParamEnum.Foo, info [5].DefaultValue, "#2");
                }
 
-#if NET_4_5
                [Test]
                public void HasDefaultValueEnum () {
                        ParameterInfo[] info = typeof (ParameterInfoTest).GetMethod ("paramMethod").GetParameters ();
 
                        Assert.IsTrue (info [5].HasDefaultValue);
                }
-#endif
 
                public static void Sample2 ([DecimalConstantAttribute(2,2,2,2,2)] decimal a, [DateTimeConstantAttribute(123456)] DateTime b) {}
 
@@ -125,7 +123,6 @@ namespace MonoTests.System.Reflection
                        Assert.AreEqual (pi [1].DefaultValue.GetType (), typeof (Missing), "#2");
                }
 
-#if NET_4_5
                [Test]
                public void TestHasDefaultValues ()
                {
@@ -135,7 +132,6 @@ namespace MonoTests.System.Reflection
                        Assert.IsFalse (pi [1].HasDefaultValue, "#2");
                        Assert.IsTrue (pi [2].HasDefaultValue, "#3");
                }
-#endif
 
                public void Sample (int a, [Optional] int b, object c = null)
                {
@@ -252,13 +248,11 @@ namespace MonoTests.System.Reflection
                        Assert.AreEqual (decimal.MaxValue, info [0].DefaultValue);
                }
 
-#if NET_4_5
                [Test]
                public void HasDefaultValueDecimal () {
                        var info = typeof (ParameterInfoTest).GetMethod ("TestC").GetParameters ();
                        Assert.IsTrue (info [0].HasDefaultValue);
                }
-#endif
 
                class TestParamAttribute : Attribute
                {
@@ -344,13 +338,11 @@ namespace MonoTests.System.Reflection
                        Assert.AreEqual (0, p.GetCustomAttributes (typeof (FlagsAttribute), false).Length, "#3");
                        Assert.AreEqual (0, p.GetOptionalCustomModifiers ().Length, "#4");
                        Assert.AreEqual (0, p.GetRequiredCustomModifiers ().Length, "#5");
-#if NET_4_5
                        try {
                                var ign = p.HasDefaultValue;
                                Assert.Fail ("#6");
                        } catch (NotImplementedException) {
                        }
-#endif
                        Assert.IsFalse (p.IsIn, "#7");
 #if FEATURE_USE_LCID
                        Assert.IsFalse (p.IsLcid, "#8");
@@ -358,13 +350,11 @@ namespace MonoTests.System.Reflection
                        Assert.IsFalse (p.IsOptional, "#9");
                        Assert.IsFalse (p.IsOut, "#10");
                        Assert.IsFalse (p.IsRetval, "#10");
-#if NET_4_5
                        try {
                                var ign = p.CustomAttributes;
                                Assert.Fail ("#11");
                        } catch (NotImplementedException) {
                        }
-#endif
                        try {
                                p.GetCustomAttributesData ();
                                Assert.Fail ("#12");
@@ -446,9 +436,7 @@ namespace MonoTests.System.Reflection
                        Assert.IsFalse (p2.IsIn, "#1");
                        p2.MyAttrsImpl = ParameterAttributes.In;
                        Assert.IsTrue (p2.IsIn, "#2");
-#if NET_4_5
                        Assert.AreEqual (p2.myList, p2.CustomAttributes, "#3");
-#endif
                }
        }
 }
index 2fe870111ca33ce341b403cb3b48534ec9033fdf..4c4388ec8b3e17bb2eef08f784b9d42e2f934610 100644 (file)
@@ -391,7 +391,12 @@ namespace MonoTests.System.Reflection
                        var p = t.GetProperty ("Prop");
                        Assert.AreEqual ("test", p.GetConstantValue (), "#1");
 
-                       File.Delete (Path.Combine (Path.GetTempPath (), an));
+                       try {
+                               // This throws an exception under MS.NET and Mono on Windows,
+                               // open files cannot be deleted. That's fine.
+                               File.Delete (Path.Combine (Path.GetTempPath (), an));
+                       } catch (Exception) {
+                       }
 
                        var pa = typeof (TestE).GetProperty ("PropE");
                        try {
index 88690944df3851ad2a9d846b0fbbae50723d8eb5..55f00dd8bede15797ed25b02495180e54f79ccfb 100644 (file)
@@ -28,15 +28,9 @@ namespace MonoTests.System.Resources
                [TestFixtureSetUp]
                public void FixtureSetUp ()
                {
-                       char ds = Path.DirectorySeparatorChar;
-                       if (ds == '/') {
-                               string base_path = Path.Combine (Directory.GetCurrentDirectory (), Path.Combine ("Test", "resources"));
-                               m_ResourceFile = Path.Combine (base_path, "MyResources.resources");
-                               m_BadResourceFile = Path.Combine (base_path, "Empty.resources");
-                       } else {
-                               m_ResourceFile = Path.Combine ("Test", Path.Combine ("resources", "MyResources.resources"));
-                               m_BadResourceFile = "resources" + ds + "Empty.resources";
-                       }
+                       string base_path = Path.Combine (Directory.GetCurrentDirectory (), Path.Combine ("Test", "resources"));
+                       m_ResourceFile = Path.Combine (base_path, "MyResources.resources");
+                       m_BadResourceFile = Path.Combine (base_path, "Empty.resources");
                }
 
                [SetUp]
index 5edb1274e33022cf25d0c464da4e3ad918d8689c..c442b3c7b890ee3eb27420618a8462692df7627a 100644 (file)
@@ -26,7 +26,6 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_4_5
 
 using System;
 using System.Threading;
@@ -117,4 +116,3 @@ namespace MonoTests.System.Runtime.CompilerServices
        }
 }
 
-#endif
\ No newline at end of file
index 57b1d2c27642c1dafc45d854a7ccf92f086f1cee..c9d7aca855bc8a1fa9eb64ccd193d34715fd6e38 100644 (file)
@@ -26,7 +26,6 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_4_5
 
 using System;
 using System.Threading;
@@ -396,4 +395,3 @@ namespace MonoTests.System.Runtime.CompilerServices
        }
 }
 
-#endif
index 31242816cd8b55d9d5da0746dcdabb52d4b5bdf7..867a06cabc57031a5ac00b9017a0f23d4d6605ab 100644 (file)
@@ -26,7 +26,6 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_4_5
 
 using System;
 using System.Threading;
@@ -173,4 +172,3 @@ namespace MonoTests.System.Runtime.CompilerServices
        }
 }
 
-#endif
\ No newline at end of file
index cc53f6a8d99a221337ae91ef80686c61ed619ceb..fbb1d821157a422ff8a4d63a007eadb5f45a24e7 100644 (file)
@@ -26,7 +26,6 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_4_5
 
 using System;
 using System.Collections.Generic;
@@ -183,4 +182,3 @@ namespace MonoTests.System.Runtime.CompilerServices
        }
 }
 
-#endif
\ No newline at end of file
index d0acc240428b4ada7b89cd9496e6b479b3dfabb7..d4ca72dc0a94857730af44a9635cffa80624a605 100644 (file)
@@ -208,8 +208,8 @@ namespace MonoTests.System.Runtime.InteropServices
                [Test]
                public void GetHINSTANCE ()
                {
-                       if (RunningOnUnix)
-                               Assert.Ignore ("GetHINSTANCE only applies to Windows.");
+                       if (RunningOnMono)
+                               Assert.Ignore ("GetHINSTANCE only applies to .NET on Windows.");
 
                        Assembly a;
                        IntPtr hinstance;
@@ -260,6 +260,15 @@ namespace MonoTests.System.Runtime.InteropServices
                        }
                }
 #endif
+
+               [Test]
+               public void GetHRForException ()
+               {
+                       Assert.AreEqual (0, Marshal.GetHRForException (null));
+                       Assert.IsTrue (Marshal.GetHRForException (new Exception ()) < 0);
+                       Assert.AreEqual (12345, Marshal.GetHRForException (new IOException ("test message", 12345)));
+               }
+
                [Test] // bug #319009
                public void StringToHGlobalUni ()
                {
@@ -298,9 +307,7 @@ namespace MonoTests.System.Runtime.InteropServices
                                Assert.AreEqual (0x1234, Marshal.ReadInt16 (ptr));
                                Assert.AreEqual (0x1234, Marshal.ReadInt16 (ptr, 0));
                                Assert.AreEqual (0x4567, Marshal.ReadInt16 (ptr, 2));
-#if NET_4_5
                                Assert.AreEqual (0x4567, Marshal.ReadInt16 ((ptr + 5)));
-#endif
                                Assert.AreEqual (0x4567, Marshal.ReadInt16 (ptr, 5));
                        } finally {
                                Marshal.FreeHGlobal (ptr);
@@ -318,9 +325,7 @@ namespace MonoTests.System.Runtime.InteropServices
                                Assert.AreEqual (0x12345678, Marshal.ReadInt32 (ptr));
                                Assert.AreEqual (0x12345678, Marshal.ReadInt32 (ptr, 0));
                                Assert.AreEqual (0x77654321, Marshal.ReadInt32 (ptr, 4));
-#if NET_4_5
                                Assert.AreEqual (0x77654321, Marshal.ReadInt32 ((ptr + 10)));
-#endif
                                Assert.AreEqual (0x77654321, Marshal.ReadInt32 (ptr, 10));
                        } finally {
                                Marshal.FreeHGlobal (ptr);
@@ -798,10 +803,9 @@ namespace MonoTests.System.Runtime.InteropServices
                        ex = Marshal.GetExceptionForHR (E_INVALIDARG);
                        Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "E_INVALIDARG");
                }
-               bool RunningOnUnix {
+               bool RunningOnMono {
                        get {
-                               int p = (int) Environment.OSVersion.Platform;
-                               return ((p == 4) || (p == 128) || (p == 6));
+                               return (Type.GetType ("System.MonoType", false) != null);
                        }
                }
 
@@ -818,6 +822,151 @@ namespace MonoTests.System.Runtime.InteropServices
                        int nSize
                );
 #endif
+
+               [StructLayout( LayoutKind.Sequential, Pack = 1 )]
+               public class FourByteStruct
+               {
+                       public UInt16 value1;
+                       public UInt16 value2;
+               }
+
+               [StructLayout( LayoutKind.Sequential, Pack = 1 )]
+               public class ByteArrayFourByteStruct : FourByteStruct
+               {
+                       [MarshalAs( UnmanagedType.ByValArray, SizeConst = 5 )]
+                       public byte[] array;
+               }
+
+               [StructLayout( LayoutKind.Sequential, Pack = 1 )]
+               public class SingleByteStruct
+               {
+                       public byte value1;
+               }
+
+               [StructLayout( LayoutKind.Sequential, Pack = 1 )]
+               public class ByteArraySingleByteStruct : SingleByteStruct
+               {
+                       [MarshalAs( UnmanagedType.ByValArray, SizeConst = 5 )]
+                       public byte[] array1;
+                       public byte value2;
+               }
+
+               [StructLayout( LayoutKind.Sequential, Pack = 1 )]
+               public class ByteArraySingleByteChildStruct : ByteArraySingleByteStruct
+               {
+                       [MarshalAs( UnmanagedType.ByValArray, SizeConst = 5 )]
+                       public byte[] array2;
+               }
+
+               [Test]
+               public void CheckByteArrayFourByteStruct()
+               {
+                       ByteArrayFourByteStruct myStruct = new ByteArrayFourByteStruct
+                       { value1 = 42, value2 = 53, array = Encoding.UTF8.GetBytes( "Hello" ) };
+
+                       byte[] buffer = Serialize (myStruct);
+
+                       UInt16 value1 = BitConverter.ToUInt16 (buffer, 0);
+                       UInt16 value2 = BitConverter.ToUInt16 (buffer, 2);
+                       string array = Encoding.UTF8.GetString (buffer, 4, 5);
+
+                       Assert.AreEqual((UInt16)42, value1);
+                       Assert.AreEqual((UInt16)53, value2);
+                       Assert.AreEqual ("Hello", array);
+               }
+
+               [Test]
+               public void CheckByteArraySingleByteChildStruct()
+               {
+                       ByteArraySingleByteChildStruct myStruct = new ByteArraySingleByteChildStruct
+                       { value1 = 42, array1 = Encoding.UTF8.GetBytes( "Hello" ), value2 = 53,  array2 = Encoding.UTF8.GetBytes( "World" ) };
+
+                       byte[] array = Serialize (myStruct);
+
+                       byte value1 = array [0];
+                       string array1 = Encoding.UTF8.GetString (array, 1, 5);
+                       byte value2 = array [6];
+                       string array2 = Encoding.UTF8.GetString (array, 7, 5);
+
+                       Assert.AreEqual((byte)42, value1);
+                       Assert.AreEqual ("Hello", array1);
+                       Assert.AreEqual((byte)53, value2);
+                       Assert.AreEqual ("World", array2);
+               }
+
+               [StructLayout(LayoutKind.Sequential, Pack = 1)]
+               public struct FiveByteStruct
+               {
+                       public uint uIntField;
+                       public byte byteField;
+               };
+
+               [StructLayout(LayoutKind.Sequential, Pack = 1)]
+               public class Base
+               {
+                       public ushort firstUShortField;
+                       public ushort secondUShortField;
+               }
+
+               [StructLayout(LayoutKind.Sequential, Pack = 1)]
+               public class Derived : Base
+               {
+                       [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
+                       public FiveByteStruct[] arrayField;
+               }
+
+               [Test]
+               public void CheckPtrToStructureWithFixedArrayAndBaseClassFields()
+               {
+                       const int arraySize = 6;
+                       var derived = new Derived
+                       {
+                               arrayField = new FiveByteStruct[arraySize],
+                               firstUShortField = 42,
+                               secondUShortField = 43
+                       };
+
+                       for (var i = 0; i < arraySize; ++i)
+                       {
+                               derived.arrayField[i].byteField = (byte)i;
+                               derived.arrayField[i].uIntField = (uint)i * 10;
+                       }
+
+                       var array = Serialize(derived);
+                       var deserializedDerived = Deserialize<Derived>(array);
+
+                       Assert.AreEqual(derived.firstUShortField, deserializedDerived.firstUShortField, "The firstUShortField differs, which is not expected.");
+                       Assert.AreEqual(derived.secondUShortField, deserializedDerived.secondUShortField, "The secondUShortField differs, which is not expected.");
+
+                       for (var i = 0; i < arraySize; ++i)
+                       {
+                               Assert.AreEqual(derived.arrayField[i].byteField, deserializedDerived.arrayField[i].byteField, string.Format("The byteField at index {0} differs, which is not expected.", i));
+                               Assert.AreEqual(derived.arrayField[i].uIntField, deserializedDerived.arrayField[i].uIntField, string.Format("The uIntField at index {0} differs, which is not expected.", i));
+                       }
+               }
+
+               public static byte[] Serialize( object obj )
+               {
+                       int nTypeSize = Marshal.SizeOf( obj );
+                       byte[] arrBuffer = new byte[nTypeSize];
+
+                       GCHandle hGCHandle = GCHandle.Alloc( arrBuffer, GCHandleType.Pinned );
+                       IntPtr pBuffer = hGCHandle.AddrOfPinnedObject();
+                       Marshal.StructureToPtr( obj, pBuffer, false );
+                       hGCHandle.Free();
+
+                       return arrBuffer;
+               }
+
+               public static T Deserialize<T>(byte[] buffer)
+               {
+                       var handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+                       var pBuffer = handle.AddrOfPinnedObject();
+                       var objResult = (T)Marshal.PtrToStructure(pBuffer, typeof(T));
+                       handle.Free();
+
+                       return objResult;
+               }
        }
 #if !MOBILE
        [ComImport()]
index 0456cbcdd1707db16c627b196432b2626e4802a3..7eb43817eb311f11680feeb44dce84573d5a9608 100644 (file)
@@ -2,7 +2,6 @@
 // ClaimsIdentityTest.cs - NUnit Test Cases for System.Security.Claims.ClaimsIdentity
 //
 
-#if NET_4_5
 
 using NUnit.Framework;
 using System;
@@ -561,4 +560,3 @@ namespace MonoTests.System.Security.Claims
        }
 }
 
-#endif
index 3d5660d256e1ac98a409781f6f12770c5c7699d3..35734b76b028457a567bbb64116eb04f65203060 100644 (file)
@@ -3,7 +3,6 @@
 // ClaimsPrincipalTest.cs - NUnit Test Cases for System.Security.Claims.ClaimsPrincipal
 //
 
-#if NET_4_5
 
 using NUnit.Framework;
 using System;
@@ -253,4 +252,3 @@ namespace MonoTests.System.Security.Claims
        }
 }
 
-#endif
index 2c3cf5d2227850655b7dbc947928c736301c446f..a3e95c65a66d4e3fc2e40682e22b6f013a271f41 100644 (file)
@@ -145,6 +145,9 @@ public class CryptoConfigTest {
                // URL used in SignatureMethod element
                CreateFromName ("http://www.w3.org/2000/09/xmldsig#dsa-sha1", "System.Security.Cryptography.DSASignatureDescription");
                CreateFromName ("http://www.w3.org/2000/09/xmldsig#rsa-sha1", "System.Security.Cryptography.RSAPKCS1SHA1SignatureDescription");
+               CreateFromName ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", "System.Security.Cryptography.RSAPKCS1SHA256SignatureDescription");
+               CreateFromName ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha384", "System.Security.Cryptography.RSAPKCS1SHA384SignatureDescription");
+               CreateFromName ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha512", "System.Security.Cryptography.RSAPKCS1SHA512SignatureDescription");
                CreateFromName ("http://www.w3.org/2000/09/xmldsig#hmac-sha1", null);
                // URL used in DigestMethod element 
                CreateFromName ("http://www.w3.org/2000/09/xmldsig#sha1", "System.Security.Cryptography.SHA1CryptoServiceProvider");
@@ -303,17 +306,24 @@ public class CryptoConfigTest {
                MapNameToOID ("System.Security.Cryptography.SHA1", "1.3.14.3.2.26");
 //             MapNameToOID ("System.Security.Cryptography.HashAlgorithm", "1.3.14.3.2.26");
                MapNameToOID ("System.Security.Cryptography.SHA1CryptoServiceProvider", "1.3.14.3.2.26");
+               MapNameToOID ("System.Security.Cryptography.SHA1Cng", "1.3.14.3.2.26");
                MapNameToOID ("System.Security.Cryptography.SHA1Managed", "1.3.14.3.2.26");
                MapNameToOID ("MD5", "1.2.840.113549.2.5");
                MapNameToOID ("System.Security.Cryptography.MD5", "1.2.840.113549.2.5");
                MapNameToOID ("System.Security.Cryptography.MD5CryptoServiceProvider", "1.2.840.113549.2.5");
                MapNameToOID ("SHA256", "2.16.840.1.101.3.4.2.1");
+               MapNameToOID ("System.Security.Cryptography.SHA256CryptoServiceProvider", "2.16.840.1.101.3.4.2.1");
+               MapNameToOID ("System.Security.Cryptography.SHA256Cng", "2.16.840.1.101.3.4.2.1");
                MapNameToOID ("System.Security.Cryptography.SHA256", "2.16.840.1.101.3.4.2.1");
                MapNameToOID ("System.Security.Cryptography.SHA256Managed", "2.16.840.1.101.3.4.2.1");
                MapNameToOID ("SHA384", "2.16.840.1.101.3.4.2.2");
+               MapNameToOID ("System.Security.Cryptography.SHA384CryptoServiceProvider", "2.16.840.1.101.3.4.2.2");
+               MapNameToOID ("System.Security.Cryptography.SHA384Cng", "2.16.840.1.101.3.4.2.2");
                MapNameToOID ("System.Security.Cryptography.SHA384", "2.16.840.1.101.3.4.2.2");
                MapNameToOID ("System.Security.Cryptography.SHA384Managed", "2.16.840.1.101.3.4.2.2");
                MapNameToOID ("SHA512", "2.16.840.1.101.3.4.2.3");
+               MapNameToOID ("System.Security.Cryptography.SHA512CryptoServiceProvider", "2.16.840.1.101.3.4.2.3");
+               MapNameToOID ("System.Security.Cryptography.SHA512Cng", "2.16.840.1.101.3.4.2.3");
                MapNameToOID ("System.Security.Cryptography.SHA512", "2.16.840.1.101.3.4.2.3");
                MapNameToOID ("System.Security.Cryptography.SHA512Managed", "2.16.840.1.101.3.4.2.3");
                MapNameToOID ("RIPEMD160", "1.3.36.3.2.1");
index c27a58f99cf7844a701f649d671d7cb79f33ae0c..44830498971db5aa2d87dd3e5274875540a1777f 100644 (file)
@@ -307,17 +307,33 @@ public class SignatureDescriptionTest {
        }
 
        [Test]
-       public void RSASignatureDescription () 
+       public void RSASignatureDescription ()
+       {
+// TODO: this would be cleaner with NUnit TestCase'es but they're NUnit 2.5+ :(
+#if FULL_AOT_RUNTIME || MONOTOUCH
+               RSASignatureDescriptionCore ("http://www.w3.org/2000/09/xmldsig#rsa-sha1", "System.Security.Cryptography.SHA1Cng", "System.Security.Cryptography.SHA1CryptoServiceProvider");
+               RSASignatureDescriptionCore ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", "System.Security.Cryptography.SHA256Cng", "System.Security.Cryptography.SHA256Managed");
+               RSASignatureDescriptionCore ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha384", "System.Security.Cryptography.SHA384Cng", "System.Security.Cryptography.SHA384Managed");
+               RSASignatureDescriptionCore ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha512", "System.Security.Cryptography.SHA512Cng", "System.Security.Cryptography.SHA512Managed");
+#else
+               RSASignatureDescriptionCore ("http://www.w3.org/2000/09/xmldsig#rsa-sha1", "System.Security.Cryptography.SHA1Cng", "System.Security.Cryptography.SHA1Cng");
+               RSASignatureDescriptionCore ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", "System.Security.Cryptography.SHA256Cng", "System.Security.Cryptography.SHA256Cng");
+               RSASignatureDescriptionCore ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha384", "System.Security.Cryptography.SHA384Cng", "System.Security.Cryptography.SHA384Cng");
+               RSASignatureDescriptionCore ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha512", "System.Security.Cryptography.SHA512Cng", "System.Security.Cryptography.SHA512Cng");
+#endif
+       }
+
+       void RSASignatureDescriptionCore (string name, string expectedDigestAlgorithm, string expectedSelectedDigestAlgorithm) 
        {
                // internal class - we cannot create one without CryptoConfig
-               SignatureDescription sd = (SignatureDescription) CryptoConfig.CreateFromName ("http://www.w3.org/2000/09/xmldsig#rsa-sha1");
-               Assert.AreEqual ("System.Security.Cryptography.SHA1Cng", sd.DigestAlgorithm);
+               SignatureDescription sd = (SignatureDescription) CryptoConfig.CreateFromName (name);
+               Assert.AreEqual (expectedDigestAlgorithm, sd.DigestAlgorithm);
                Assert.AreEqual ("System.Security.Cryptography.RSAPKCS1SignatureDeformatter", sd.DeformatterAlgorithm);
                Assert.AreEqual ("System.Security.Cryptography.RSAPKCS1SignatureFormatter", sd.FormatterAlgorithm);
                Assert.AreEqual ("System.Security.Cryptography.RSA", sd.KeyAlgorithm);
 
                HashAlgorithm hash = sd.CreateDigest();
-               Assert.AreEqual ("System.Security.Cryptography.SHA1Cng", hash.ToString ());
+               Assert.AreEqual (expectedSelectedDigestAlgorithm, hash.ToString ());
 
                Assert.AreEqual ("System.Security.Cryptography.RSA", sd.KeyAlgorithm);
 
index 00aa374348db05be7dae57d541cf5275cc326c31..f75b723ff45947e8b9fab4c54e1c47e48f539c18 100644 (file)
@@ -229,7 +229,7 @@ namespace MonoTests.System.Security.Policy {
                        "http://*.go-mono.com",
                        "http://www.go-mono.com:8080/index.html",
                        "mono://unknown/protocol",
-                       Path.DirectorySeparatorChar + "mono" + Path.DirectorySeparatorChar + "index.html",
+                       "/mono/index.html",
                };
 
                [Test]
index 16fca588d1e4a395222bdd3c7e335fba2b898143..f35a9d3883062cb04a0eaeeeff65f3ef43dc9116 100644 (file)
@@ -119,6 +119,40 @@ namespace MonoTests.System.Text
                                Assert.AreEqual (testchars [i], (char) bytes [i]);
                }
 
+               [Test] // Test GetBytes(string)
+               public void TestGetBytes7 ()
+               {
+                       var latin1_encoding = Encoding.GetEncoding ("latin1");
+
+                       var expected = new byte [] { 0x3F, 0x20, 0x3F, 0x20, 0x3F };
+                       var actual = latin1_encoding.GetBytes("\u24c8 \u2075 \u221e"); // normal replacement
+                       Assert.AreEqual (expected, actual, "#1");
+
+                       expected = new byte [] { 0x3F, 0x3F };
+                       actual = latin1_encoding.GetBytes("\ud83d\ude0a"); // surrogate pair replacement
+                       Assert.AreEqual (expected, actual, "#2");
+
+                       expected = new byte [] { 0x3F, 0x3F, 0x20 };
+                       actual = latin1_encoding.GetBytes("\ud83d\ude0a "); // surrogate pair replacement
+                       Assert.AreEqual (expected, actual, "#3");
+
+                       expected = new byte [] { 0x20, 0x20, 0x3F, 0x3F, 0x20, 0x20 };
+                       actual = latin1_encoding.GetBytes("  \ud83d\ude0a  "); // surrogate pair replacement
+                       Assert.AreEqual (expected, actual, "#4");
+
+                       expected = new byte [] { 0x20, 0x20, 0x3F, 0x3F, 0x20, 0x20 };
+                       actual = latin1_encoding.GetBytes("  \ud834\udd1e  "); // surrogate pair replacement
+                       Assert.AreEqual (expected, actual, "#5");
+
+                       expected = new byte [] { 0x41, 0x42, 0x43, 0x00, 0x41, 0x42, 0x43 };
+                       actual = latin1_encoding.GetBytes("ABC\0ABC"); // embedded zero byte not replaced
+                       Assert.AreEqual (expected, actual, "#6");
+
+                       expected = new byte [] { 0x20, 0x20, 0x3F, 0x20, 0x20 };
+                       actual = latin1_encoding.GetBytes("  \ud834  "); // invalid surrogate pair replacement
+                       Assert.AreEqual (expected, actual, "#7");
+               }
+
                [Test] // Test GetChars(byte[])
                public void TestGetChars1 () 
                {
@@ -212,6 +246,15 @@ namespace MonoTests.System.Text
                        Assert.AreEqual (string.Empty, encoding.GetString (new byte [0], 0, 0), "#2");
                }
 
+               [Test]
+               [ExpectedException (typeof (EncoderFallbackException))]
+               public void EncoderFallback ()
+               {
+                       Encoding e = Encoding.ASCII.Clone () as Encoding;
+                       e.EncoderFallback = new EncoderExceptionFallback ();
+                       e.GetBytes ("\u24c8");
+               }
+
                [Test]
                [ExpectedException (typeof (DecoderFallbackException))]
                public void DecoderFallback ()
diff --git a/mcs/class/corlib/Test/System.Text/Latin1EncodingTest.cs b/mcs/class/corlib/Test/System.Text/Latin1EncodingTest.cs
new file mode 100644 (file)
index 0000000..0195967
--- /dev/null
@@ -0,0 +1,350 @@
+//
+// Latin1EncodingTest.cs
+//
+// Author:
+//     Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// Copyright (C) 2016 Xamarin, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Text;
+
+using NUnit.Framework;
+using NUnit.Framework.Constraints;
+
+#if !MOBILE
+using NUnit.Framework.SyntaxHelpers;
+#endif
+
+namespace MonoTests.System.Text
+{
+       [TestFixture]
+       public class Latin1EncodingTest
+       {
+               private char[] testchars;
+               private byte[] testbytes;
+
+               [SetUp]
+               public void SetUp ()
+               {
+                       testchars = new char[4];
+                       testchars[0] = 'T';
+                       testchars[1] = 'e';
+                       testchars[2] = 's';
+                       testchars[3] = 't';
+                       testbytes = new byte[4];
+                       testbytes[0] = (byte) 'T';
+                       testbytes[1] = (byte) 'e';
+                       testbytes[2] = (byte) 's';
+                       testbytes[3] = (byte) 't';
+               }
+
+               [Test]
+               public void IsBrowserDisplay ()
+               {
+                       Assert.IsTrue (Encoding.GetEncoding ("latin1").IsBrowserDisplay);
+               }
+
+               [Test]
+               public void IsBrowserSave ()
+               {
+                       Assert.IsTrue (Encoding.GetEncoding ("latin1").IsBrowserSave);
+               }
+
+               [Test]
+               public void IsMailNewsDisplay ()
+               {
+                       Assert.IsTrue (Encoding.GetEncoding ("latin1").IsMailNewsDisplay);
+               }
+
+               [Test]
+               public void IsMailNewsSave ()
+               {
+                       Assert.IsTrue (Encoding.GetEncoding ("latin1").IsMailNewsSave);
+               }
+
+               [Test] // Test GetBytes(char[])
+               public void TestGetBytes1 () 
+               {
+                       Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
+                       byte[] bytes = latin1_encoding.GetBytes(testchars);
+                       for (int i = 0; i < testchars.Length; i++)
+                               Assert.AreEqual (testchars[i], (char) bytes[i]);
+               }
+
+               [Test] // Test GetBytes(char[], int, int)
+               public void TestGetBytes2 () 
+               {
+                       Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
+                       byte[] bytes = latin1_encoding.GetBytes(testchars, 1, 1);
+                       Assert.AreEqual (1, bytes.Length, "#1");
+                       Assert.AreEqual (testchars [1], (char) bytes [0], "#2");
+               }
+
+               [Test] // Test non-Latin1 char in char[]
+               public void TestGetBytes3 () 
+               {
+                       Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
+                       testchars[2] = (char) 0x100;
+                       byte[] bytes = latin1_encoding.GetBytes(testchars);
+                       Assert.AreEqual ('T', (char) bytes [0], "#1");
+                       Assert.AreEqual ('e', (char) bytes [1], "#2");
+                       Assert.AreEqual ('?', (char) bytes [2], "#3");
+                       Assert.AreEqual ('t', (char) bytes [3], "#4");
+               }
+
+               [Test] // Test GetBytes(char[], int, int, byte[], int)
+               public void TestGetBytes4 () 
+               {
+                       Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
+                       byte[] bytes = new Byte[1];
+                       int cnt = latin1_encoding.GetBytes(testchars, 1, 1, bytes, 0);
+                       Assert.AreEqual (1, cnt, "#1");
+                       Assert.AreEqual (testchars [1], (char) bytes [0], "#2");
+               }
+
+               [Test] // Test GetBytes(string, int, int, byte[], int)
+               public void TestGetBytes5 () 
+               {
+                       Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
+                       byte[] bytes = new Byte[1];
+                       int cnt = latin1_encoding.GetBytes("Test", 1, 1, bytes, 0);
+                       Assert.AreEqual ('e', (char) bytes [0], "#1");
+               }
+
+               [Test] // Test GetBytes(string)
+               public void TestGetBytes6 () 
+               {
+                       Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
+                       byte[] bytes = latin1_encoding.GetBytes("Test");
+                       for (int i = 0; i < testchars.Length; i++)
+                               Assert.AreEqual (testchars [i], (char) bytes [i]);
+               }
+
+               [Test] // Test GetBytes(string)
+               public void TestGetBytes7 ()
+               {
+                       var latin1_encoding = Encoding.GetEncoding ("latin1");
+
+                       var expected = new byte [] { 0x3F, 0x20, 0x3F, 0x20, 0x3F };
+                       var actual = latin1_encoding.GetBytes("\u24c8 \u2075 \u221e"); // normal replacement
+                       Assert.AreEqual (expected, actual, "#1");
+
+                       expected = new byte [] { 0x3F, 0x3F };
+                       actual = latin1_encoding.GetBytes("\ud83d\ude0a"); // surrogate pair replacement
+                       Assert.AreEqual (expected, actual, "#2");
+
+                       expected = new byte [] { 0x3F, 0x3F, 0x20 };
+                       actual = latin1_encoding.GetBytes("\ud83d\ude0a "); // surrogate pair replacement
+                       Assert.AreEqual (expected, actual, "#3");
+
+                       expected = new byte [] { 0x20, 0x20, 0x3F, 0x3F, 0x20, 0x20 };
+                       actual = latin1_encoding.GetBytes("  \ud83d\ude0a  "); // surrogate pair replacement
+                       Assert.AreEqual (expected, actual, "#4");
+
+                       expected = new byte [] { 0x20, 0x20, 0x3F, 0x3F, 0x20, 0x20 };
+                       actual = latin1_encoding.GetBytes("  \ud834\udd1e  "); // surrogate pair replacement
+                       Assert.AreEqual (expected, actual, "#5");
+
+                       expected = new byte [] { 0x41, 0x42, 0x43, 0x00, 0x41, 0x42, 0x43 };
+                       actual = latin1_encoding.GetBytes("ABC\0ABC"); // embedded zero byte not replaced
+                       Assert.AreEqual (expected, actual, "#6");
+
+                       expected = new byte [] { 0x20, 0x20, 0x3F, 0x20, 0x20 };
+                       actual = latin1_encoding.GetBytes("  \ud834  "); // invalid surrogate pair replacement
+                       Assert.AreEqual (expected, actual, "#7");
+               }
+
+               [Test] // Test GetChars(byte[])
+               public void TestGetChars1 () 
+               {
+                       Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
+                       char[] chars = latin1_encoding.GetChars(testbytes);
+                       for (int i = 0; i < testbytes.Length; i++)
+                               Assert.AreEqual (testbytes[i], (byte) chars[i]);
+               }
+
+               [Test] // Test GetChars(byte[], int, int)
+               public void TestGetChars2 () 
+               {
+                       Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
+                       char[] chars = latin1_encoding.GetChars(testbytes, 1, 1);
+                       Assert.AreEqual (1, chars.Length, "#1");
+                       Assert.AreEqual (testbytes [1], (byte) chars [0], "#2");
+               }
+
+               [Test] // Test GetChars(byte[], int, int, char[], int)
+               public void TestGetChars4 () 
+               {
+                       Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
+                       char[] chars = new char[1];
+                       int cnt = latin1_encoding.GetChars(testbytes, 1, 1, chars, 0);
+                       Assert.AreEqual (1, cnt, "#1");
+                       Assert.AreEqual (testbytes [1], (byte) chars [0], "#2");
+               }
+
+               [Test] // Test GetString(char[])
+               public void TestGetString1 () 
+               {
+                       Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
+                       string str = latin1_encoding.GetString(testbytes);
+                       Assert.AreEqual ("Test", str);
+               }
+
+               [Test] // Test GetString(char[], int, int)
+               public void TestGetString2 () 
+               {
+                       Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
+                       string str = latin1_encoding.GetString(testbytes, 1, 2);
+                       Assert.AreEqual ("es", str);
+               }
+
+               [Test] // Test Decoder
+               public void TestDecoder ()
+               {
+                       Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
+                       char[] chars = new char[1];
+                       int cnt = latin1_encoding.GetDecoder().GetChars(testbytes, 1, 1, chars, 0);
+                       Assert.AreEqual (1, cnt, "#1");
+                       Assert.AreEqual (testbytes [1], (byte) chars [0], "#2");
+               }
+
+               [Test] // Test Decoder
+               public void TestEncoder ()
+               {
+                       Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
+                       byte[] bytes = new Byte[1];
+                       int cnt = latin1_encoding.GetEncoder().GetBytes(testchars, 1, 1, bytes, 0, false);
+                       Assert.AreEqual (1, cnt, "#1");
+                       Assert.AreEqual (testchars [1], (char) bytes [0], "#2");
+               }
+
+               [Test]
+               public void TestZero ()
+               {
+                       Encoding encoding = Encoding.GetEncoding ("latin1");
+                       Assert.AreEqual (string.Empty, encoding.GetString (new byte [0]), "#1");
+                       Assert.AreEqual (string.Empty, encoding.GetString (new byte [0], 0, 0), "#2");
+               }
+
+               [Test]
+               [ExpectedException (typeof (EncoderFallbackException))]
+               public void EncoderFallback ()
+               {
+                       Encoding e = Encoding.GetEncoding ("latin1").Clone () as Encoding;
+                       e.EncoderFallback = new EncoderExceptionFallback ();
+                       e.GetBytes ("\u24c8");
+               }
+
+               [Test]
+       //      [ExpectedException (typeof (ArgumentException))]
+               public void DecoderFallback2 ()
+               {
+                       var bytes = new byte[] {
+                               0x30, 0xa0, 0x31, 0xa8
+                       };
+                       var enc = (Encoding)Encoding.GetEncoding ("latin1").Clone ();
+                       enc.DecoderFallback = new TestFallbackDecoder ();
+                       
+                       var chars = new char [7];
+                       var ret = enc.GetChars (bytes, 0, bytes.Length, chars, 0);
+                       Console.WriteLine (ret);
+                       
+                       for (int i = 0; i < chars.Length; i++) {
+                               Console.Write ("{0:x2} ", (int)chars [i]);
+                       }
+                       Console.WriteLine ();
+               }
+               
+               [Test]
+               public void DecoderFallback3 ()
+               {
+                       var bytes = new byte[] {
+                               0x30, 0xa0, 0x31, 0xa8
+                       };
+                       var enc = (Encoding)Encoding.GetEncoding ("latin1").Clone ();
+                       enc.DecoderFallback = new TestFallbackDecoder ();
+                       
+                       var chars = new char[] { '9', '8', '7', '6', '5' };
+                       var ret = enc.GetChars (bytes, 0, bytes.Length, chars, 0);
+                       
+                       Assert.That (ret, Is.EqualTo (4), "ret");
+                       Assert.That (chars [0], Is.EqualTo ('0'), "chars[0]");
+                       Assert.That (chars [1], Is.EqualTo ((char)0xA0), "chars[1]");
+                       Assert.That (chars [2], Is.EqualTo ('1'), "chars[2]");
+                       Assert.That (chars [3], Is.EqualTo ((char)0xA8), "chars[3]");
+                       Assert.That (chars [4], Is.EqualTo ('5'), "chars[4]");
+               }
+               
+               class TestFallbackDecoder : DecoderFallback {
+                       const int count = 2;
+                       
+                       public override int MaxCharCount {
+                               get { return count; }
+                       }
+                       
+                       public override DecoderFallbackBuffer CreateFallbackBuffer ()
+                       {
+                               return new Buffer ();
+                       }
+                       
+                       class Buffer : DecoderFallbackBuffer {
+                               char[] queue;
+                               int index;
+                               
+                               public override int Remaining {
+                                       get {
+                                               return queue.Length - index;
+                                       }
+                               }
+                               
+                               public override char GetNextChar ()
+                               {
+                                       return index < queue.Length ? queue [index++] : '\0';
+                               }
+                               
+                               public override bool Fallback (byte[] bytes, int unused)
+                               {
+                                       queue = new char[bytes.Length * count];
+                                       index = 0;
+                                       for (int i = 0; i < bytes.Length; i++) {
+                                               for (int j = 0; j < count; j++)
+                                                       queue [index++] = (char)(bytes [i]+j);
+                                       }
+                                       return true;
+                               }
+                               
+                               public override bool MovePrevious ()
+                               {
+                                       throw new NotImplementedException ();
+                               }
+                               
+                               public override void Reset ()
+                               {
+                                       base.Reset ();
+                               }
+                       }
+               }
+
+       }
+}
index a02ffe96986af87a5e7c90d811c9f4f2d5b5fe40..264095d8b31bafd1cb5add47ca69b91397fe7d04 100644 (file)
@@ -24,7 +24,6 @@
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 // THE SOFTWARE.
 
-#if NET_4_5
 
 using System;
 using System.Threading;
@@ -176,4 +175,3 @@ namespace MonoTests.System.Threading.Tasks
        }
 }
 
-#endif
\ No newline at end of file
index e0b127a0bc708543bfa39f3f3f6d7aa59c6e93ac..f4e8a9705f78e0beeacafc11313de8475cea8a30 100644 (file)
@@ -409,7 +409,6 @@ namespace MonoTests.System.Threading.Tasks
                        Assert.IsTrue (tasks[1].IsCanceled, "#4");
                }
 
-#if NET_4_5            
                [Test]
                public void WaitAll_CancelledAndTimeout ()
                {
@@ -418,7 +417,6 @@ namespace MonoTests.System.Threading.Tasks
                        var t2 = Task.Delay (3000);
                        Assert.IsFalse (Task.WaitAll (new[] { t1, t2 }, 10));
                }
-#endif
 
                [Test]
                public void WaitAllExceptionThenCancelled ()
@@ -1057,24 +1055,21 @@ namespace MonoTests.System.Threading.Tasks
                        var token = source.Token;
                        var evt = new ManualResetEventSlim ();
                        bool result = false;
-                       bool thrown = false;
 
-                       var task = Task.Factory.StartNew (() => evt.Wait (100));
+                       var task = Task.Factory.StartNew (() => { Assert.IsTrue (evt.Wait (2000), "#1"); });
                        var cont = task.ContinueWith (t => result = true, token, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
 
                        source.Cancel();
                        evt.Set ();
-                       task.Wait (100);
+                       Assert.IsTrue (task.Wait (2000), "#2");
                        try {
-                               cont.Wait (100);
-                       } catch (Exception ex) {
-                               thrown = true;
+                               Assert.IsFalse (cont.Wait (4000), "#3");
+                       } catch (AggregateException ex) {
                        }
 
-                       Assert.IsTrue (task.IsCompleted);
-                       Assert.IsTrue (cont.IsCanceled);
-                       Assert.IsFalse (result);
-                       Assert.IsTrue (thrown);
+                       Assert.IsTrue (task.IsCompleted, "#4");
+                       Assert.IsTrue (cont.IsCanceled, "#5");
+                       Assert.IsFalse (result, "#6");
                }
 
                [Test]
@@ -1219,7 +1214,6 @@ namespace MonoTests.System.Threading.Tasks
                        }
                }
 
-#if NET_4_5
                [Test]
                public void ContinuationOnBrokenScheduler ()
                {
@@ -2114,6 +2108,5 @@ namespace MonoTests.System.Threading.Tasks
                        }
                }
                
-#endif
        }
 }
index 3a80f5ae0d294e288b2c4785045290fb9bc149bc..f5b4dd9a3ba1d029449ab8125eaf508c6710cca2 100644 (file)
@@ -38,7 +38,6 @@ namespace MonoTests.System.Threading
        [TestFixture]
        public class CancellationTokenSourceTest
        {
-#if NET_4_5
 
                [Test]
                public void Ctor_Invalid ()
@@ -100,7 +99,6 @@ namespace MonoTests.System.Threading
                        Assert.AreEqual (0, called, "#1");
                }
 
-#endif
 
                [Test]
                public void Token ()
@@ -345,13 +343,11 @@ namespace MonoTests.System.Threading
                        } catch (ObjectDisposedException) {
                        }
 
-#if NET_4_5
                        try {
                                cts.CancelAfter (1);
                                Assert.Fail ("#6");
                        } catch (ObjectDisposedException) {
                        }
-#endif
                }
 
                [Test]
@@ -478,7 +474,6 @@ namespace MonoTests.System.Threading
                        }
                }
 
-#if NET_4_5
                [Test]
                public void DisposeRace ()
                {
@@ -490,7 +485,6 @@ namespace MonoTests.System.Threading
                                c1.Dispose ();
                        }
                }
-#endif
        }
 }
 
index c0e50b9cb89eac2814730d6ad97bcb0e61b3d79c..005a9d86887a3e97952f5ac36f4d7557d8c10883 100644 (file)
@@ -43,6 +43,18 @@ namespace MonoTests.System.Threading {
                {
                        new EventWaitHandle (true, (EventResetMode) Int32.MinValue);
                }
+
+               [Test]
+               public void Disposed_Set ()
+               {
+                       var ewh = new EventWaitHandle (false, EventResetMode.ManualReset);
+                       ewh.Dispose();
+                       try {
+                               ewh.Set();
+                               Assert.Fail ();
+                       } catch (ObjectDisposedException) {
+                       }
+               }
        }
 }
 
index a869f7191f7daf9d8ba55795b459e8f909b117a2..4c6694f1e17f137b4112f86e51c0081a24041b53 100644 (file)
@@ -94,25 +94,6 @@ namespace MonoTests.System.Threading
                //TimeSpan MaxValue = TimeSpan.FromMilliseconds ((long) Int32.MaxValue);
                TimeSpan TooLarge = TimeSpan.FromMilliseconds ((long) Int32.MaxValue + 1);
 
-               static bool is_win32;
-               static bool is_mono;
-
-               static ThreadTest ()
-               {
-                       switch (Environment.OSVersion.Platform) {
-                       case PlatformID.Win32NT:
-                       case PlatformID.Win32S:
-                       case PlatformID.Win32Windows:
-                       case PlatformID.WinCE:
-                               is_win32 = true;
-                               break;
-                       }
-
-                       // check a class in mscorlib to determine if we're running on Mono
-                       if (Type.GetType ("Mono.Runtime", false) != null)
-                               is_mono = true;
-               }
-
                //Some Classes to test as threads
                private class C1Test
                {
@@ -327,8 +308,6 @@ namespace MonoTests.System.Threading
                [Category ("NotDotNet")] // it hangs.
                public void TestStart()
                {
-                       if (is_win32 && is_mono)
-                               Assert.Fail ("This test fails on Win32. The test should be fixed.");
                {
                        C1Test test1 = new C1Test();
                        Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
@@ -370,9 +349,6 @@ namespace MonoTests.System.Threading
                [Test]
                public void TestApartmentState ()
                {
-                       if (is_win32 && is_mono)
-                               Assert.Fail ("This test fails on mono on win32. Our runtime should be fixed.");
-
                        C2Test test1 = new C2Test();
                        Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
                        Assert.AreEqual (ApartmentState.Unknown, TestThread.ApartmentState, "#1");
@@ -390,9 +366,6 @@ namespace MonoTests.System.Threading
                [Category ("NotWorking")] // setting the priority of a Thread before it is started isn't implemented in Mono yet
                public void TestPriority1()
                {
-                       if (is_win32 && is_mono)
-                               Assert.Fail ("This test fails on mono on Win32. Our runtime should be fixed.");
-
                        C2Test test1 = new C2Test();
                        Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
                        try {
@@ -487,9 +460,6 @@ namespace MonoTests.System.Threading
                [Test]
                public void TestIsBackground1 ()
                {
-                       if (is_win32 && is_mono)
-                               Assert.Fail ("This test fails on mono on Win32. Our runtime should be fixed.");
-
                        C2Test test1 = new C2Test();
                        Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
                        try {
@@ -534,9 +504,6 @@ namespace MonoTests.System.Threading
                [Test]
                public void TestName()
                {
-                       if (is_win32 && is_mono)
-                               Assert.Fail ("This test fails on mono on Win32. Our runtime should be fixed.");
-
                        C2Test test1 = new C2Test();
                        Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
                        try {
@@ -696,9 +663,6 @@ namespace MonoTests.System.Threading
                [Test]
                public void TestThreadState ()
                {
-                       if (is_win32 && is_mono)
-                               Assert.Fail ("This test fails on mono on Win32. Our runtime should be fixed.");
-
                        //TODO: Test The rest of the possible transitions
                        C2Test test1 = new C2Test();
                        Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
@@ -830,9 +794,6 @@ namespace MonoTests.System.Threading
                [Category("NotDotNet")] // On MS, ThreadStateException is thrown on Abort: "Thread is suspended; attempting to abort"
                public void TestSuspendAbort ()
                {
-                       if (is_win32 && is_mono)
-                               Assert.Fail ("This test fails on Win32. The test should be fixed.");
-
                        Thread t = new Thread (new ThreadStart (DoCount));
                        t.IsBackground = true;
                        t.Start ();
@@ -898,7 +859,6 @@ namespace MonoTests.System.Threading
                }
                
                [Test]
-               [Category ("NotDotNet")] // it crashes nunit.
                public void Test_InterruptCurrentThread ()
                {
                        ManualResetEvent mre = new ManualResetEvent (false);
@@ -937,6 +897,7 @@ namespace MonoTests.System.Threading
 
 #if MONO_FEATURE_MULTIPLE_APPDOMAINS
                [Test]
+               [Category ("NotDotNet")]
                public void CurrentThread_Domains ()
                {
                        AppDomain ad = AppDomain.CreateDomain ("foo");
index 3743ea2b3072db737686c848c994d29e323b68e6..c3b37a99407bccce894b569ccb9265cb19a9579f 100644 (file)
@@ -26,7 +26,6 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_4_5
 
 using System;
 using System.Threading;
@@ -146,5 +145,4 @@ namespace MonoTests.System.Threading
        }
 }
 
-#endif
 
index 121d1c45f10a88ceae0f80fdbbfe3575d7f7cb70..387d0318a3f45cc6eb627e3241dd6ad2bd40704a 100644 (file)
@@ -23,8 +23,12 @@ namespace MonoTests.System
 
                private bool RunningOnWindows {
                        get {
-                               int os = (int)Environment.OSVersion.Platform;
-                               return (os != 4);
+                               return Path.DirectorySeparatorChar == '\\';
+                       }
+               }
+               private bool RunningOnMono {
+                       get {
+                               return (Type.GetType ("System.MonoType", false) != null);
                        }
                }
 
@@ -72,22 +76,18 @@ namespace MonoTests.System
                [Test]
                public void ApplicationBase1 ()
                {
-                       string expected_path = tmpPath.Replace(@"\", @"/");
+                       string expected_path = tmpPath;
                        AppDomainSetup setup = new AppDomainSetup ();
-                       string fileUri = "file://" + expected_path;
+                       string fileUri = "file://" + tmpPath.Replace(@"\", @"/");
                        setup.ApplicationBase = fileUri;
-                       // with MS 1.1 SP1 the expected_path starts with "//" but this make
-                       // sense only under Windows (i.e. reversed \\ for local files)
-                       if (RunningOnWindows)
-                               expected_path = "//" + expected_path;
                        try {
-                               // under 2.0 the NotSupportedException is throw when getting 
+                               // under .NET the NotSupportedException is throw when getting 
                                // (and not setting) the ApplicationBase property
                                Assert.AreEqual (expected_path, setup.ApplicationBase);
                        }
                        catch (NotSupportedException) {
-                               // however the path is invalid only on Windows
-                               if (!RunningOnWindows)
+                               // however the path is invalid only on .NET
+                               if (RunningOnMono)
                                        throw;
                        }
                }
@@ -114,16 +114,17 @@ namespace MonoTests.System
                {
                        AppDomainSetup setup = new AppDomainSetup ();
                        setup.ApplicationBase = "lala:la";
-                       try {
-                               // under 2.0 the NotSupportedException is throw when getting 
-                               // (and not setting) the ApplicationBase property
+                       if (!RunningOnWindows) {
                                Assert.AreEqual (Path.GetFullPath ("lala:la"), setup.ApplicationBase);
-                       }
-                       catch (NotSupportedException) {
-                               // however the path is invalid only on Windows
-                               // (same exceptions as Path.GetFullPath)
-                               if (!RunningOnWindows)
-                                       throw;
+                       } else {
+                               // On Windows we expect a NotSupportedException to be thrown because
+                               // of the illegal character (:) in the path
+                               try {
+                                       Assert.Fail ("NotSupportedException expected but setup.ApplicationBase returned:" + setup.ApplicationBase);
+                               }
+                               catch (NotSupportedException) {
+                                       // Expected
+                               }
                        }
                }
 
@@ -133,16 +134,18 @@ namespace MonoTests.System
                        // This is failing because of (probably) a windows-ism, so don't worry
                        AppDomainSetup setup = new AppDomainSetup ();
                        setup.ApplicationBase = "file:///lala:la";
-                       try {
-                               // under 2.0 the NotSupportedException is throw when getting 
-                               // (and not setting) the ApplicationBase property
-                               Assert.AreEqual ("/lala:la", setup.ApplicationBase);
-                       }
-                       catch (NotSupportedException) {
-                               // however the path is invalid only on Windows
-                               // (same exceptions as Path.GetFullPath)
-                               if (!RunningOnWindows)
-                                       throw;
+                       string expected = "/lala:la";
+                       if (!RunningOnWindows) {
+                               Assert.AreEqual (expected, setup.ApplicationBase);
+                       } else {
+                               // On Windows we expect a NotSupportedException to be thrown because
+                               // of the illegal character (:) in the path
+                               try {
+                                       Assert.Fail ("NotSupportedException expected but setup.ApplicationBase returned:" + setup.ApplicationBase);
+                               }
+                               catch (NotSupportedException) {
+                                       // Expected
+                               }
                        }
                }
 
@@ -153,19 +156,45 @@ namespace MonoTests.System
                        setup.ApplicationBase = "la?lala";
                        // paths containing "?" are *always* bad on Windows
                        // but are legal for linux so we return a full path
-                       if (RunningOnWindows) {
+                       if (!RunningOnWindows) {
+                               Assert.AreEqual (Path.GetFullPath ("la?lala"), setup.ApplicationBase);
+                       } else {
+                               // On Windows we expect a ArgumentException to be thrown because
+                               // of the illegal character (?) in the path
                                try {
-                                       // ArgumentException is throw when getting 
-                                       // (and not setting) the ApplicationBase property
-                                       Assert.Fail ("setup.ApplicationBase returned :" + setup.ApplicationBase);
+                                       Assert.Fail ("ArgumentException expected but setup.ApplicationBase returned:" + setup.ApplicationBase);
                                }
                                catch (ArgumentException) {
+                                       // Expected
+                               }
+                       }
+               }
+
+               [Test]
+               public void ApplicationBase7 ()
+               {
+                       if (RunningOnWindows) {
+                               // Extended paths are Windows only
+                               AppDomainSetup setup = new AppDomainSetup ();
+                               string expected = @"\\?\" + curDir;
+                               setup.ApplicationBase = expected;
+                               Assert.AreEqual (expected, setup.ApplicationBase);
+                       }
+               }
+
+               [Test]
+               public void ApplicationBase8 ()
+               {
+                       if (RunningOnWindows) {
+                               // Extended paths are Windows only
+                               AppDomainSetup setup = new AppDomainSetup ();
+                               setup.ApplicationBase = @"\\?\C:\lala:la";
+                               try {
+                                       Assert.Fail ("NotSupportedException expected but setup.ApplicationBase returned:" + setup.ApplicationBase);
                                }
-                               catch (Exception e) {
-                                       Assert.Fail ("Unexpected exception: " + e.ToString ());
+                               catch (NotSupportedException) {
+                                       // Expected
                                }
-                       } else {
-                               Assert.AreEqual (Path.GetFullPath ("la?lala"), setup.ApplicationBase);
                        }
                }
 
index 28588f8e008664c9ee0dc501fa0ae6e27db06dec..7fa93e8fcf1d628928fea25b2df5360d21751f54 100644 (file)
@@ -156,7 +156,6 @@ namespace MonoTests.System
                        Assert.AreEqual (myArrSeg_1 != myArrSeg_2, true);
                }
 
-#if NET_4_5
                [Test]
                public void IList_NotSupported ()
                {
@@ -278,6 +277,5 @@ namespace MonoTests.System
                        IList<byte> seg = new ArraySegment<byte> (arr);
                        seg[4] = 3;
                }
-#endif
        }
 }
index 1d9f1a10bc689454df138a2256dc41e9c338aaa8..93676f9dd091647595efdf15b49b50b16660ac50 100644 (file)
@@ -332,7 +332,6 @@ public class ConsoleTest
 
 #if !MOBILE
 
-#if NET_4_5
        [Test]
        public void RedirectedTest ()
        {
@@ -343,7 +342,6 @@ public class ConsoleTest
                Console.SetError (TextWriter.Null);
                Assert.IsFalse (Console.IsErrorRedirected);
        }
-#endif
 
        // Bug 678357
        [Test]
index e1d95dc93f00f563a4a7415708b3714d5a107a4f..ba664353ab9e0056492a1ae525057969609af25e 100644 (file)
@@ -1445,6 +1445,18 @@ namespace MonoTests.System
                        var del = Delegate.Remove (del1, del2);
                }
 
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void CreateDelegateThrowsAnArgumentExceptionWhenCalledWithAnOpenGeneric()
+               {
+                       var m = GetType().GetMethod("AnyGenericMethod");
+                       Delegate.CreateDelegate(typeof(Action), this, m);
+               }
+
+               public void AnyGenericMethod<T>()
+               {
+               }
+
                static bool Int32D2 (int x, int y)
                {
                        return (x & y) == y; 
index 30fe1dce81793175172850c761f64df3b888b4b9..45d7ee110519c0c7a01f1d5e155b064f5f965eb0 100644 (file)
@@ -147,6 +147,7 @@ namespace MonoTests.System
                }
 
                [Test]
+               [Culture ("en-US")]
                public void Parse ()
                {
                        int i = 0;
index 55a6ea2ecfe4c6d11c609802597b1c11d7f5d63b..5e3811bca0019d8a6964049b9387ea5943157eff 100644 (file)
@@ -674,6 +674,14 @@ namespace MonoTests.System
                                Assert.AreEqual (expectedDate, lastMidnightAsEST);
                                Assert.AreEqual (lastMidnight, lastMidnightAsPST);
                        }
+
+                       [Test]
+                       public void ConvertTimeBySystemTimeZoneId_UtcId ()
+                       {
+                               DateTime localTime = TimeZoneInfo.ConvertTime (DateTime.UtcNow, TimeZoneInfo.Utc, TimeZoneInfo.Local);
+
+                               TimeZoneInfo.ConvertTimeBySystemTimeZoneId (DateTime.UtcNow, TimeZoneInfo.Utc.Id, TimeZoneInfo.Local.Id);
+                       }
                }
                
                [TestFixture]
index 717a99b6e1cba9263ce50e2ee00abdde649a65d3..b94afe1013da0b7ef3ceb012df27cb8d1875932d 100644 (file)
@@ -124,7 +124,6 @@ namespace MonoTests.System {
                        Assert.IsFalse (Foo.failed);
                }
 
-#if NET_4_5
                [Test]
                public void WeakReferenceT_TryGetTarget_NullTarget ()
                {
@@ -132,7 +131,6 @@ namespace MonoTests.System {
                        object obj;
                        Assert.IsFalse (r.TryGetTarget (out obj), "#1");
                }
-#endif
        }
 }
 
diff --git a/mcs/class/corlib/coreclr/AsyncLocal.cs b/mcs/class/corlib/coreclr/AsyncLocal.cs
deleted file mode 100644 (file)
index 5b7b61f..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics.Contracts;
-using System.Security;
-
-namespace System.Threading
-{
-    //
-    // AsyncLocal<T> represents "ambient" data that is local to a given asynchronous control flow, such as an
-    // async method.  For example, say you want to associate a culture with a given async flow:
-    //
-    // static AsyncLocal<Culture> s_currentCulture = new AsyncLocal<Culture>();
-    //
-    // static async Task SomeOperationAsync(Culture culture)
-    // {
-    //    s_currentCulture.Value = culture;
-    //
-    //    await FooAsync();
-    // }
-    //
-    // static async Task FooAsync()
-    // {
-    //    PrintStringWithCulture(s_currentCulture.Value);
-    // }
-    //
-    // AsyncLocal<T> also provides optional notifications when the value associated with the current thread
-    // changes, either because it was explicitly changed by setting the Value property, or implicitly changed
-    // when the thread encountered an "await" or other context transition.  For example, we might want our
-    // current culture to be communicated to the OS as well:
-    //
-    // static AsyncLocal<Culture> s_currentCulture = new AsyncLocal<Culture>(
-    //   args =>
-    //   {
-    //      NativeMethods.SetThreadCulture(args.CurrentValue.LCID);
-    //   });
-    //
-    public sealed class AsyncLocal<T> : IAsyncLocal
-    {
-        [SecurityCritical] // critical because this action will terminate the process if it throws.
-        private readonly Action<AsyncLocalValueChangedArgs<T>> m_valueChangedHandler;
-
-        //
-        // Constructs an AsyncLocal<T> that does not receive change notifications.
-        //
-        public AsyncLocal() 
-        {
-        }
-
-        //
-        // Constructs an AsyncLocal<T> with a delegate that is called whenever the current value changes
-        // on any thread.
-        //
-        [SecurityCritical]
-        public AsyncLocal(Action<AsyncLocalValueChangedArgs<T>> valueChangedHandler) 
-        {
-            m_valueChangedHandler = valueChangedHandler;
-        }
-
-        public T Value
-        {
-            [SecuritySafeCritical]
-            get 
-            { 
-#if MONO
-                throw new NotImplementedException ();
-#else                
-                object obj = ExecutionContext.GetLocalValue(this);
-                return (obj == null) ? default(T) : (T)obj;
-#endif                
-            }
-            [SecuritySafeCritical]
-            set 
-            {
-#if MONO
-                throw new NotImplementedException ();
-#else                
-                ExecutionContext.SetLocalValue(this, value, m_valueChangedHandler != null); 
-#endif
-            }
-        }
-
-        [SecurityCritical]
-        void IAsyncLocal.OnValueChanged(object previousValueObj, object currentValueObj, bool contextChanged)
-        {
-            Contract.Assert(m_valueChangedHandler != null);
-            T previousValue = previousValueObj == null ? default(T) : (T)previousValueObj;
-            T currentValue = currentValueObj == null ? default(T) : (T)currentValueObj;
-            m_valueChangedHandler(new AsyncLocalValueChangedArgs<T>(previousValue, currentValue, contextChanged));
-        }
-    }
-
-    //
-    // Interface to allow non-generic code in ExecutionContext to call into the generic AsyncLocal<T> type.
-    //
-    internal interface IAsyncLocal
-    {
-        [SecurityCritical]
-        void OnValueChanged(object previousValue, object currentValue, bool contextChanged);
-    }
-
-    public struct AsyncLocalValueChangedArgs<T>
-    {
-        public T PreviousValue { get; private set; }
-        public T CurrentValue { get; private set; }
-        
-        //
-        // If the value changed because we changed to a different ExecutionContext, this is true.  If it changed
-        // because someone set the Value property, this is false.
-        //
-        public bool ThreadContextChanged { get; private set; }
-
-        internal AsyncLocalValueChangedArgs(T previousValue, T currentValue, bool contextChanged)
-            : this()
-        {
-            PreviousValue = previousValue;
-            CurrentValue = currentValue;
-            ThreadContextChanged = contextChanged;
-        }
-    }
-}
\ No newline at end of file
diff --git a/mcs/class/corlib/coreclr/DisablePrivateReflectionAttribute.cs b/mcs/class/corlib/coreclr/DisablePrivateReflectionAttribute.cs
deleted file mode 100644 (file)
index c510478..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-namespace System.Runtime.CompilerServices
-{
-    using System;
-
-    [AttributeUsage(AttributeTargets.Assembly, AllowMultiple=false, Inherited=false)]
-    public sealed class DisablePrivateReflectionAttribute : Attribute
-    {
-        public DisablePrivateReflectionAttribute() {}
-    }
-}
-
diff --git a/mcs/class/corlib/coreclr/EncodingProvider.cs b/mcs/class/corlib/coreclr/EncodingProvider.cs
deleted file mode 100644 (file)
index 82024ce..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-namespace System.Text
-{
-    using System;
-    using System.Collections;
-    using System.Collections.Generic;
-
-    [System.Runtime.InteropServices.ComVisible(true)]
-    public abstract class EncodingProvider
-    {
-        public EncodingProvider() { }
-        public abstract Encoding GetEncoding(string name);
-        public abstract Encoding GetEncoding(int codepage);
-
-        // GetEncoding should return either valid encoding or null. shouldn't throw any exception except on null name
-        public virtual Encoding GetEncoding(string name, EncoderFallback encoderFallback, DecoderFallback decoderFallback)
-        {
-            Encoding enc = GetEncoding(name);
-            if (enc != null)
-            {
-                enc = (Encoding)GetEncoding(name).Clone();
-                enc.EncoderFallback = encoderFallback;
-                enc.DecoderFallback = decoderFallback;
-            }
-
-            return enc;
-        }
-
-        public virtual Encoding GetEncoding(int codepage, EncoderFallback encoderFallback, DecoderFallback decoderFallback)
-        {
-            Encoding enc = GetEncoding(codepage);
-            if (enc != null)
-            {
-                enc = (Encoding)GetEncoding(codepage).Clone();
-                enc.EncoderFallback = encoderFallback;
-                enc.DecoderFallback = decoderFallback;
-            }
-
-            return enc;
-        }
-
-        internal static void AddProvider(EncodingProvider provider)
-        {
-            if (provider == null)
-                throw new ArgumentNullException("provider");
-
-            lock (s_InternalSyncObject)
-            {
-                if (s_providers == null)
-                {
-                    s_providers = new EncodingProvider[1] { provider };
-                    return;
-                }
-
-                if (Array.IndexOf(s_providers, provider) >= 0)
-                {
-                    return;
-                }
-
-                var providers = new EncodingProvider[s_providers.Length + 1];
-                Array.Copy(s_providers, providers, s_providers.Length);
-                providers[providers.Length - 1] = provider;
-                s_providers = providers;
-            }
-        }
-
-        internal static Encoding GetEncodingFromProvider(int codepage)
-        {
-            if (s_providers == null)
-                return null;
-
-            var providers = s_providers;
-            foreach (EncodingProvider provider in providers)
-            {
-                Encoding enc = provider.GetEncoding(codepage);
-                if (enc != null)
-                    return enc;
-            }
-
-            return null;
-        }
-
-        internal static Encoding GetEncodingFromProvider(string encodingName)
-        {
-            if (s_providers == null)
-                return null;
-
-            var providers = s_providers;
-            foreach (EncodingProvider provider in providers)
-            {
-                Encoding enc = provider.GetEncoding(encodingName);
-                if (enc != null)
-                    return enc;
-            }
-
-            return null;
-        }
-
-        internal static Encoding GetEncodingFromProvider(int codepage, EncoderFallback enc, DecoderFallback dec)
-        {
-            if (s_providers == null)
-                return null;
-
-            var providers = s_providers;
-            foreach (EncodingProvider provider in providers)
-            {
-                Encoding encing = provider.GetEncoding(codepage, enc, dec);
-                if (encing != null)
-                    return encing;
-            }
-
-            return null;
-        }
-
-        internal static Encoding GetEncodingFromProvider(string encodingName, EncoderFallback enc, DecoderFallback dec)
-        {
-            if (s_providers == null)
-                return null;
-
-            var providers = s_providers;
-            foreach (EncodingProvider provider in providers)
-            {
-                Encoding encoding = provider.GetEncoding(encodingName, enc, dec);
-                if (encoding != null)
-                    return encoding;
-            }
-
-            return null;
-        }
-
-        private static Object s_InternalSyncObject = new Object();
-        private static volatile EncodingProvider[] s_providers;
-    }
-}
diff --git a/mcs/class/corlib/coreclr/FormattableString.cs b/mcs/class/corlib/coreclr/FormattableString.cs
deleted file mode 100644 (file)
index 420421b..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved. 
-// Licensed under the MIT license. See LICENSE file in the project root for full license information. 
-
-/*============================================================
-**
-** Class:  FormattableString
-**
-**
-** Purpose: implementation of the FormattableString
-** class.
-**
-===========================================================*/
-namespace System
-{
-    /// <summary>
-    /// A composite format string along with the arguments to be formatted. An instance of this
-    /// type may result from the use of the C# or VB language primitive "interpolated string".
-    /// </summary>
-    public abstract class FormattableString : IFormattable
-    {
-        /// <summary>
-        /// The composite format string.
-        /// </summary>
-        public abstract string Format { get; }
-
-        /// <summary>
-        /// Returns an object array that contains zero or more objects to format. Clients should not
-        /// mutate the contents of the array.
-        /// </summary>
-        public abstract object[] GetArguments();
-
-        /// <summary>
-        /// The number of arguments to be formatted.
-        /// </summary>
-        public abstract int ArgumentCount { get; }
-
-        /// <summary>
-        /// Returns one argument to be formatted from argument position <paramref name="index"/>.
-        /// </summary>
-        public abstract object GetArgument(int index);
-
-        /// <summary>
-        /// Format to a string using the given culture.
-        /// </summary>
-        public abstract string ToString(IFormatProvider formatProvider);
-
-        string IFormattable.ToString(string ignored, IFormatProvider formatProvider)
-        {
-            return ToString(formatProvider);
-        }
-
-        /// <summary>
-        /// Format the given object in the invariant culture. This static method may be
-        /// imported in C# by
-        /// <code>
-        /// using static System.FormattableString;
-        /// </code>.
-        /// Within the scope
-        /// of that import directive an interpolated string may be formatted in the
-        /// invariant culture by writing, for example,
-        /// <code>
-        /// Invariant($"{{ lat = {latitude}; lon = {longitude} }}")
-        /// </code>
-        /// </summary>
-        public static string Invariant(FormattableString formattable)
-        {
-            if (formattable == null)
-            {
-                throw new ArgumentNullException("formattable");
-            }
-
-            return formattable.ToString(Globalization.CultureInfo.InvariantCulture);
-        }
-
-        public override string ToString()
-        {
-            return ToString(Globalization.CultureInfo.CurrentCulture);
-        }
-    }
-}
diff --git a/mcs/class/corlib/coreclr/FormattableStringFactory.cs b/mcs/class/corlib/coreclr/FormattableStringFactory.cs
deleted file mode 100644 (file)
index 990204c..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved. 
-// Licensed under the MIT license. See LICENSE file in the project root for full license information. 
-
-/*============================================================
-**
-** Class:  FormattableStringFactory
-**
-**
-** Purpose: implementation of the FormattableStringFactory
-** class.
-**
-===========================================================*/
-namespace System.Runtime.CompilerServices
-{
-    /// <summary>
-    /// A factory type used by compilers to create instances of the type <see cref="FormattableString"/>.
-    /// </summary>
-    public static class FormattableStringFactory
-    {
-        /// <summary>
-        /// Create a <see cref="FormattableString"/> from a composite format string and object
-        /// array containing zero or more objects to format.
-        /// </summary>
-        public static FormattableString Create(string format, params object[] arguments)
-        {
-            if (format == null)
-            {
-                throw new ArgumentNullException("format");
-            }
-
-            if (arguments == null)
-            {
-                throw new ArgumentNullException("arguments");
-            }
-
-            return new ConcreteFormattableString(format, arguments);
-        }
-
-        private sealed class ConcreteFormattableString : FormattableString
-        {
-            private readonly string _format;
-            private readonly object[] _arguments;
-
-            internal ConcreteFormattableString(string format, object[] arguments)
-            {
-                _format = format;
-                _arguments = arguments;
-            }
-
-            public override string Format { get { return _format; } }
-            public override object[] GetArguments() { return _arguments; }
-            public override int ArgumentCount { get { return _arguments.Length; } }
-            public override object GetArgument(int index) { return _arguments[index]; }
-            public override string ToString(IFormatProvider formatProvider) { return string.Format(formatProvider, _format, _arguments); }
-        }
-    }
-}
diff --git a/mcs/class/corlib/coreclr/WaitHandleExtensions.cs b/mcs/class/corlib/coreclr/WaitHandleExtensions.cs
deleted file mode 100644 (file)
index 93dbc6f..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-//
-
-using Microsoft.Win32.SafeHandles;
-using System.Security;
-
-namespace System.Threading
-{
-    public static class WaitHandleExtensions
-    {
-        /// <summary>
-        /// Gets the native operating system handle.
-        /// </summary>
-        /// <param name="waitHandle">The <see cref="System.Threading.WaitHandle"/> to operate on.</param>
-        /// <returns>A <see cref="System.Runtime.InteropServices.SafeHandle"/> representing the native operating system handle.</returns>
-        [SecurityCritical]
-        public static SafeWaitHandle GetSafeWaitHandle(this WaitHandle waitHandle)
-        {
-            if (waitHandle == null)
-            {
-                throw new ArgumentNullException("waitHandle");
-            }
-
-            return waitHandle.SafeWaitHandle;
-        }
-
-        /// <summary>
-        /// Sets the native operating system handle
-        /// </summary>
-        /// <param name="waitHandle">The <see cref="System.Threading.WaitHandle"/> to operate on.</param>
-        /// <param name="value">A <see cref="System.Runtime.InteropServices.SafeHandle"/> representing the native operating system handle.</param>
-        [SecurityCritical]
-        public static void SetSafeWaitHandle(this WaitHandle waitHandle, SafeWaitHandle value)
-        {
-            if (waitHandle == null)
-            {
-                throw new ArgumentNullException("waitHandle");
-            }
-
-            waitHandle.SafeWaitHandle = value;
-        }
-    }
-}
\ No newline at end of file
index 9ef22797a960de09c6ac8e1a3998cebcebdf8dbd..6e253d6ff77128c7e034d704e67e2fde23434eb6 100644 (file)
@@ -700,7 +700,7 @@ System.Security.AccessControl/SecurityInfos.cs
 System.Security.AccessControl/SystemAcl.cs
 System.Security.Cryptography/CryptoAPITransform.cs
 System.Security.Cryptography/CryptoConfig.cs
-System.Security.Cryptography/CryptoConfig_2_1.cs
+System.Security.Cryptography/CryptoConfig.common.cs
 System.Security.Cryptography/CryptoConfig.fullaot.cs
 System.Security.Cryptography/CspKeyContainerInfo.cs
 System.Security.Cryptography/DESCryptoServiceProvider.cs
@@ -849,7 +849,6 @@ System.Text/EncodingHelper.cs
 System.Text/NormalizationForm.cs
 System.Text/Latin1Encoding.cs
 System.Threading/CompressedStack.cs
-System.Threading/EventWaitHandle.cs
 System.Threading/HostExecutionContext.cs
 System.Threading/HostExecutionContextManager.cs
 System.Threading/Interlocked.cs
@@ -965,6 +964,7 @@ ReferenceSources/PathInternal.cs
 ../referencesource/mscorlib/system/fieldaccessexception.cs
 ../referencesource/mscorlib/system/flagsattribute.cs
 ../referencesource/mscorlib/system/formatexception.cs
+../referencesource/mscorlib/system/FormattableString.cs
 ../referencesource/mscorlib/system/guid.cs
 ../referencesource/mscorlib/system/iappdomain.cs
 ../referencesource/mscorlib/system/iappdomainsetup.cs
@@ -1354,10 +1354,12 @@ ReferenceSources/PathInternal.cs
 ../referencesource/mscorlib/system/runtime/compilerservices/datetimeconstantattribute.cs
 ../referencesource/mscorlib/system/runtime/compilerservices/decimalconstantattribute.cs
 ../referencesource/mscorlib/system/runtime/compilerservices/decoratednameattribute.cs
+../referencesource/mscorlib/system/runtime/compilerservices/disableprivatereflectionattribute.cs
 ../referencesource/mscorlib/system/runtime/compilerservices/discardableattribute.cs
 ../referencesource/mscorlib/system/runtime/compilerservices/extensionattribute.cs
 ../referencesource/mscorlib/system/runtime/compilerservices/fixedaddressvaluetypeattribute.cs
 ../referencesource/mscorlib/system/runtime/compilerservices/fixedbufferattribute.cs
+../referencesource/mscorlib/system/runtime/compilerservices/FormattableStringFactory.cs
 ../referencesource/mscorlib/system/runtime/compilerservices/hascopysemanticsattribute.cs
 ../referencesource/mscorlib/system/runtime/compilerservices/IAsyncStateMachine.cs
 ../referencesource/mscorlib/system/runtime/compilerservices/indexernameattribute.cs
@@ -1496,6 +1498,7 @@ ReferenceSources/PathInternal.cs
 ../referencesource/mscorlib/system/text/encoderreplacementfallback.cs
 ../referencesource/mscorlib/system/text/encoding.cs
 ../referencesource/mscorlib/system/text/encodinginfo.cs
+../referencesource/mscorlib/system/text/encodingprovider.cs
 ../referencesource/mscorlib/system/text/mlangcodepageencoding.cs
 ../referencesource/mscorlib/system/text/surrogateencoder.cs
 ../referencesource/mscorlib/system/text/unicodeencoding.cs
@@ -1564,12 +1567,14 @@ ReferenceSources/PathInternal.cs
 
 ../referencesource/mscorlib/system/threading/abandonedmutexexception.cs
 ../referencesource/mscorlib/system/threading/apartmentstate.cs
+../referencesource/mscorlib/system/threading/asynclocal.cs
 ../referencesource/mscorlib/system/threading/autoresetevent.cs
 ../referencesource/mscorlib/system/threading/CancellationToken.cs
 ../referencesource/mscorlib/system/threading/CancellationTokenRegistration.cs
 ../referencesource/mscorlib/system/threading/CancellationTokenSource.cs
 ../referencesource/mscorlib/system/threading/CountdownEvent.cs
 ../referencesource/mscorlib/system/threading/eventresetmode.cs
+../referencesource/mscorlib/system/threading/eventwaithandle.cs
 ../referencesource/mscorlib/system/threading/executioncontext.cs
 ../referencesource/mscorlib/system/threading/LazyInitializer.cs
 ../referencesource/mscorlib/system/threading/lockrecursionexception.cs
@@ -1597,6 +1602,7 @@ ReferenceSources/PathInternal.cs
 ../referencesource/mscorlib/system/threading/waithandlecannotbeopenedexception.cs
 ../referencesource/mscorlib/system/threading/threadpool.cs
 ../referencesource/mscorlib/system/threading/waithandle.cs
+../referencesource/mscorlib/system/threading/waithandleExtensions.cs
 
 ../referencesource/mscorlib/system/threading/Tasks/AsyncCausalityTracer.cs
 ../referencesource/mscorlib/system/threading/Tasks/BeginEndAwaitableAdapter.cs
@@ -1625,10 +1631,3 @@ ReferenceSources/PathInternal.cs
 
 ReferenceSources/String.cs
 ReferenceSources/Type.cs
-
-coreclr/AsyncLocal.cs
-coreclr/DisablePrivateReflectionAttribute.cs
-coreclr/EncodingProvider.cs
-coreclr/FormattableString.cs
-coreclr/FormattableStringFactory.cs
-coreclr/WaitHandleExtensions.cs
index cfd6b74ae03874680cbda5a79f32ae2f9999953c..bfa344cf598ae671dca5b6e25920aebe05be733e 100644 (file)
@@ -405,6 +405,7 @@ System.Text/EncoderTest.cs
 System.Text/EncodingTest.cs
 System.Text/EncodingTester.cs
 System.Text/EncodingInfoTest.cs
+System.Text/Latin1EncodingTest.cs
 System.Text/StringBuilderTest.cs
 System.Text/TestEncoding.cs
 System.Text/UnicodeEncodingTest.cs
index 6acc765c090d0c5e18bf7673c56328dbb30053a8..9d688d51c5ccacc0ab774d9ee3c2cb383ac0f397 100644 (file)
@@ -1,15 +1 @@
-#include corlib.dll.sources
-CommonCrypto/CommonCrypto.cs
-CommonCrypto/CryptorTransform.cs
-CommonCrypto/FastCryptorTransform.cs
-CommonCrypto/CorlibExtras.cs
-CommonCrypto/RijndaelManaged.cs
-CommonCrypto/SecRandom.cs
-CommonCrypto/RC4CommonCrypto.cs
-System/Environment.iOS.cs
-System/Guid.MonoTouch.cs
-System/NotSupportedException.iOS.cs
-CoreFoundation/CFHelpers.cs
-System.Security.Cryptography.X509Certificates/X509CertificateImplApple.cs
-System.Security.Cryptography.X509Certificates/X509Helper.Apple.cs
-System.Text/EncodingHelper.MonoTouch.cs
+#include monotouch_corlib.dll.sources
index 6acc765c090d0c5e18bf7673c56328dbb30053a8..9d688d51c5ccacc0ab774d9ee3c2cb383ac0f397 100644 (file)
@@ -1,15 +1 @@
-#include corlib.dll.sources
-CommonCrypto/CommonCrypto.cs
-CommonCrypto/CryptorTransform.cs
-CommonCrypto/FastCryptorTransform.cs
-CommonCrypto/CorlibExtras.cs
-CommonCrypto/RijndaelManaged.cs
-CommonCrypto/SecRandom.cs
-CommonCrypto/RC4CommonCrypto.cs
-System/Environment.iOS.cs
-System/Guid.MonoTouch.cs
-System/NotSupportedException.iOS.cs
-CoreFoundation/CFHelpers.cs
-System.Security.Cryptography.X509Certificates/X509CertificateImplApple.cs
-System.Security.Cryptography.X509Certificates/X509Helper.Apple.cs
-System.Text/EncodingHelper.MonoTouch.cs
+#include monotouch_corlib.dll.sources
index 6acc765c090d0c5e18bf7673c56328dbb30053a8..9d688d51c5ccacc0ab774d9ee3c2cb383ac0f397 100644 (file)
@@ -1,15 +1 @@
-#include corlib.dll.sources
-CommonCrypto/CommonCrypto.cs
-CommonCrypto/CryptorTransform.cs
-CommonCrypto/FastCryptorTransform.cs
-CommonCrypto/CorlibExtras.cs
-CommonCrypto/RijndaelManaged.cs
-CommonCrypto/SecRandom.cs
-CommonCrypto/RC4CommonCrypto.cs
-System/Environment.iOS.cs
-System/Guid.MonoTouch.cs
-System/NotSupportedException.iOS.cs
-CoreFoundation/CFHelpers.cs
-System.Security.Cryptography.X509Certificates/X509CertificateImplApple.cs
-System.Security.Cryptography.X509Certificates/X509Helper.Apple.cs
-System.Text/EncodingHelper.MonoTouch.cs
+#include monotouch_corlib.dll.sources
index 6acc765c090d0c5e18bf7673c56328dbb30053a8..9d688d51c5ccacc0ab774d9ee3c2cb383ac0f397 100644 (file)
@@ -1,15 +1 @@
-#include corlib.dll.sources
-CommonCrypto/CommonCrypto.cs
-CommonCrypto/CryptorTransform.cs
-CommonCrypto/FastCryptorTransform.cs
-CommonCrypto/CorlibExtras.cs
-CommonCrypto/RijndaelManaged.cs
-CommonCrypto/SecRandom.cs
-CommonCrypto/RC4CommonCrypto.cs
-System/Environment.iOS.cs
-System/Guid.MonoTouch.cs
-System/NotSupportedException.iOS.cs
-CoreFoundation/CFHelpers.cs
-System.Security.Cryptography.X509Certificates/X509CertificateImplApple.cs
-System.Security.Cryptography.X509Certificates/X509Helper.Apple.cs
-System.Text/EncodingHelper.MonoTouch.cs
+#include monotouch_corlib.dll.sources
index 6acc765c090d0c5e18bf7673c56328dbb30053a8..9d688d51c5ccacc0ab774d9ee3c2cb383ac0f397 100644 (file)
@@ -1,15 +1 @@
-#include corlib.dll.sources
-CommonCrypto/CommonCrypto.cs
-CommonCrypto/CryptorTransform.cs
-CommonCrypto/FastCryptorTransform.cs
-CommonCrypto/CorlibExtras.cs
-CommonCrypto/RijndaelManaged.cs
-CommonCrypto/SecRandom.cs
-CommonCrypto/RC4CommonCrypto.cs
-System/Environment.iOS.cs
-System/Guid.MonoTouch.cs
-System/NotSupportedException.iOS.cs
-CoreFoundation/CFHelpers.cs
-System.Security.Cryptography.X509Certificates/X509CertificateImplApple.cs
-System.Security.Cryptography.X509Certificates/X509Helper.Apple.cs
-System.Text/EncodingHelper.MonoTouch.cs
+#include monotouch_corlib.dll.sources
index 71341f5bc2dc3d83de248228b9d237b2d0d70b16..7da7303d755466e2c3bcdb87b7800fe0e914594a 100644 (file)
@@ -501,6 +501,44 @@ namespace System.Dynamic {
                         binder.ReturnType
                     );
 
+#if MONO // referencesource version
+                    Expression condition;
+                    // If the return type can not be assigned null then just check for type assignablity otherwise allow null.
+                    if (binder.ReturnType.IsValueType && Nullable.GetUnderlyingType(binder.ReturnType) == null) {
+                        condition = Expression.TypeIs(resultMO.Expression, binder.ReturnType);
+                    }
+                    else {
+                        condition = Expression.OrElse(
+                                        Expression.Equal(resultMO.Expression, Expression.Constant(null)),
+                                        Expression.TypeIs(resultMO.Expression, binder.ReturnType));
+                    }
+
+                    var checkedConvert = Expression.Condition(
+                        condition,
+                        convert,
+                        Expression.Throw(
+                            Expression.New(typeof(InvalidCastException).GetConstructor(new Type[]{typeof(string)}),
+                                Expression.Call(
+                                    typeof(string).GetMethod("Format", new Type[] {typeof(string), typeof(object[])}),
+                                    Expression.Constant(convertFailed),
+                                    Expression.NewArrayInit(typeof(object),
+                                        Expression.Condition(
+                                            Expression.Equal(resultMO.Expression, Expression.Constant(null)),
+                                            Expression.Constant("null"),
+                                            Expression.Call(
+                                                resultMO.Expression,
+                                                typeof(object).GetMethod("GetType")
+                                            ),
+                                            typeof(object)
+                                        )
+                                    )
+                                )
+                            ),
+                            binder.ReturnType
+                        ),
+                        binder.ReturnType
+                    );
+#else
                     var checkedConvert = Expression.Condition(
                         Expression.TypeIs(resultMO.Expression, binder.ReturnType),
                         convert,
@@ -524,6 +562,7 @@ namespace System.Dynamic {
                         ),
                         binder.ReturnType
                     );
+#endif
 
                     resultMO = new DynamicMetaObject(checkedConvert, resultMO.Restrictions);
                 }
index 19db1acb0a4349d5cb97d4570cb503ae31171d69..aeff48d0040ee4f94ed3c598c732c98e7f01ce2d 100644 (file)
@@ -155,9 +155,7 @@ namespace System.Threading
             lockID = Interlocked.Increment(ref s_nextLockID);
         }
 
-#if NET_4_5
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-#endif
         private static bool IsRWEntryEmpty(ReaderWriterCount rwc)
         {
             if (rwc.lockID == 0)
@@ -181,9 +179,7 @@ namespace System.Threading
         /// entry for this thread, but doesn't want to add one if an existing one
         /// could not be found.
         /// </summary>
-#if NET_4_5
                [MethodImpl(MethodImplOptions.AggressiveInlining)]
-#endif
         private ReaderWriterCount GetThreadRWCount(bool dontAllocate)
         {
                        ReaderWriterCount rwc = t_rwc;
@@ -1117,9 +1113,7 @@ namespace System.Threading
             return owners & READER_MASK;
         }
 
-#if NET_4_5
                [MethodImpl(MethodImplOptions.AggressiveInlining)]
-#endif
         private void EnterMyLock()
         {
             if (Interlocked.CompareExchange(ref myLock, 1, 0) != 0)
index 973773d29467b190eb5bc811cf07ab5f8f843ee4..5a68cc4744f5d95dba788357ea89a9043a963fab 100644 (file)
@@ -78,6 +78,7 @@ namespace System.IO.Ports
         }
 #endif
 
+#if !MONO
 #if FEATURE_NETCORE
         [SecuritySafeCritical]
 #endif
@@ -95,6 +96,7 @@ namespace System.IO.Ports
             int errorCode = Marshal.GetLastWin32Error();
             WinIOError(errorCode, str);
         }
+#endif
         
         // After calling GetLastWin32Error(), it clears the last error field,
         // so you must save the HResult and pass it to this method.  This method
index 360a55fa534abd5beff1d34fff8ac7d2a233e1c9..eae169c364f07c1c70e52b8a7aac444dadda66b0 100644 (file)
@@ -87,7 +87,11 @@ namespace System.Threading
                 if(null != name && 0 != name.Length && NativeMethods.ERROR_INVALID_HANDLE == errorCode)
                     throw new WaitHandleCannotBeOpenedException(SR.GetString(SR.WaitHandleCannotBeOpenedException_InvalidHandle,name));
                
+#if MONO
+                InternalResources.WinIOError(errorCode, "");
+#else
                 InternalResources.WinIOError();
+#endif
             }
             this.SafeWaitHandle = myHandle;
         }
@@ -161,7 +165,12 @@ namespace System.Threading
             {
                 if(null != name && 0 != name.Length && NativeMethods.ERROR_INVALID_HANDLE == errorCode)
                     throw new WaitHandleCannotBeOpenedException(SR.GetString(SR.WaitHandleCannotBeOpenedException_InvalidHandle,name));
+
+#if MONO
+                InternalResources.WinIOError(errorCode, "");
+#else
                 InternalResources.WinIOError();
+#endif
             }
             createdNew = errorCode != NativeMethods.ERROR_ALREADY_EXISTS;
             this.SafeWaitHandle = myHandle;
@@ -310,7 +319,11 @@ namespace System.Threading
                 if (null != name && 0 != name.Length && NativeMethods.ERROR_INVALID_HANDLE == errorCode)
                     return OpenExistingResult.NameInvalid;
                 //this is for passed through NativeMethods Errors
+#if MONO
+                InternalResources.WinIOError(errorCode, "");
+#else
                 InternalResources.WinIOError();
+#endif
             }
             result = new Semaphore(myHandle);
             return OpenExistingResult.Success;
index 756ff5d87c3c2ea70a8aa02a36da17e76e6eff18..17068f63bc9e4ad9cabf831cfc9067ba21bac739 100644 (file)
@@ -645,10 +645,7 @@ namespace System.Runtime.InteropServices{
 #endif
     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, Inherited = false)]
     [System.Runtime.InteropServices.ComVisible(true)]
-#if !MONOTOUCH
-    public
-#endif
-    sealed class ComImportAttribute : Attribute
+    public sealed class ComImportAttribute : Attribute
     {
         internal static Attribute GetCustomAttribute(RuntimeType type)
         {
index 50740031b6196b51f4c4a4759f13bea1b1674cd7..9d0439d95cff13db05c1c63d0580266f59f70d10 100644 (file)
@@ -12,7 +12,7 @@
 **
 **
 =============================================================================*/
-#if !FULL_AOT_RUNTIME
+
 namespace System.Runtime.InteropServices {
    
     using System;
@@ -31,11 +31,15 @@ namespace System.Runtime.InteropServices {
         {
             if (obj != null)
             {
+#if FULL_AOT_RUNTIME
+                throw new PlatformNotSupportedException ();
+#else
                 // Make sure this guy has an IDispatch
                 IntPtr pdisp = Marshal.GetIDispatchForObject(obj);
 
                 // If we got here without throwing an exception, the QI for IDispatch succeeded.
                 Marshal.Release(pdisp);
+#endif
             }
             m_WrappedObject = obj;
         }
@@ -51,4 +55,3 @@ namespace System.Runtime.InteropServices {
         private Object m_WrappedObject;
     }
 }
-#endif
\ No newline at end of file
index 0cf3823868c81c51fd13aeeb4f37ca1b889574ca..694412fd471faf0fd6eb03a415363e7e944e1393 100644 (file)
@@ -12,7 +12,7 @@
 **
 **
 =============================================================================*/
-#if !FULL_AOT_RUNTIME
+
 namespace System.Runtime.InteropServices {
    
     using System;
@@ -54,4 +54,3 @@ namespace System.Runtime.InteropServices {
         private int m_ErrorCode;
     }
 }
-#endif
\ No newline at end of file
index 08426b232735ae20e30bc235cfb014d7bee30992..cf9bdf17b1b19f95123dc8b0e424c6d3c2aea8ce 100644 (file)
@@ -16,6 +16,7 @@
 =============================================================================*/
 
 
+#if !MOBILE
 #if !FEATURE_MACL
 namespace System.Security.AccessControl
 {
@@ -27,6 +28,7 @@ namespace System.Security.AccessControl
     }
 }
 #endif
+#endif
 
 namespace System.Threading
 {
@@ -63,13 +65,24 @@ namespace System.Threading
             Contract.EndContractBlock();
             
             SafeWaitHandle _handle = null;
+#if MONO
+            int errorCode;
+#endif
             switch(mode)
             {
                 case EventResetMode.ManualReset:
+#if MONO
+                    _handle = new SafeWaitHandle (NativeEventCalls.CreateEvent_internal (true, initialState, name, out errorCode), true);
+#else
                     _handle = Win32Native.CreateEvent(null, true, initialState, name);
+#endif
                     break;
                 case EventResetMode.AutoReset:
+#if MONO
+                    _handle = new SafeWaitHandle (NativeEventCalls.CreateEvent_internal (false, initialState, name, out errorCode), true);
+#else
                     _handle = Win32Native.CreateEvent(null, false, initialState, name);
+#endif
                     break;
 
                 default:
@@ -78,7 +91,9 @@ namespace System.Threading
                 
             if (_handle.IsInvalid)
             {
+#if !MONO
                 int errorCode = Marshal.GetLastWin32Error();
+#endif
             
                 _handle.SetHandleAsInvalid();
                 if(null != name && 0 != name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode)
@@ -108,6 +123,7 @@ namespace System.Threading
             }
             Contract.EndContractBlock();
             Win32Native.SECURITY_ATTRIBUTES secAttrs = null;
+#if !MONO
 #if FEATURE_MACL
             // For ACL's, get the security descriptor from the EventWaitHandleSecurity.
             if (eventSecurity != null) {
@@ -119,6 +135,7 @@ namespace System.Threading
                 Buffer.Memcpy(pSecDescriptor, 0, sd, 0, sd.Length);
                 secAttrs.pSecurityDescriptor = pSecDescriptor;
             }
+#endif
 #endif
 
             SafeWaitHandle _handle = null;
@@ -136,8 +153,13 @@ namespace System.Threading
                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag",name));
             };
 
+#if MONO
+            int errorCode;
+            _handle = new SafeWaitHandle (NativeEventCalls.CreateEvent_internal (isManualReset, initialState, name, out errorCode), true);
+#else
             _handle = Win32Native.CreateEvent(secAttrs, isManualReset, initialState, name);
             int errorCode = Marshal.GetLastWin32Error();
+#endif
 
             if (_handle.IsInvalid)
             {
@@ -239,15 +261,26 @@ namespace System.Threading
 
             result = null;
 
+#if MOBILE
+            throw new NotSupportedException ();
+#else
+
+#if MONO
+            int errorCode;
+            var myHandle = new SafeWaitHandle (NativeEventCalls.OpenEvent_internal (name, rights, out errorCode), true);
+#else
 #if FEATURE_MACL
             SafeWaitHandle myHandle = Win32Native.OpenEvent((int) rights, false, name);
 #else
             SafeWaitHandle myHandle = Win32Native.OpenEvent(Win32Native.EVENT_MODIFY_STATE | Win32Native.SYNCHRONIZE, false, name);
+#endif
 #endif
             
             if (myHandle.IsInvalid)
             {
+#if !MONO
                 int errorCode = Marshal.GetLastWin32Error();
+#endif
 
                 if(Win32Native.ERROR_FILE_NOT_FOUND == errorCode || Win32Native.ERROR_INVALID_NAME == errorCode)
                     return OpenExistingResult.NameNotFound;
@@ -260,33 +293,52 @@ namespace System.Threading
             }
             result = new EventWaitHandle(myHandle);
             return OpenExistingResult.Success;
+#endif
         }
         [System.Security.SecuritySafeCritical]  // auto-generated
         public bool Reset()
         {
+#if MONO
+            var res = NativeEventCalls.ResetEvent(safeWaitHandle);
+#else
             bool res = Win32Native.ResetEvent(safeWaitHandle);
+#endif
             if (!res)
+#if MONO
+                throw new IOException ();
+#else
                 __Error.WinIOError();
+#endif
             return res;
         }
         [System.Security.SecuritySafeCritical]  // auto-generated
         public bool Set()
         {
+#if MONO
+            var res = NativeEventCalls.SetEvent(safeWaitHandle);
+#else
             bool res = Win32Native.SetEvent(safeWaitHandle);
+#endif
 
             if (!res)
+#if MONO
+                throw new IOException ();
+#else
                 __Error.WinIOError();
+#endif
 
             return res;
         }
 
-#if FEATURE_MACL
+#if FEATURE_MACL || MOBILE
         [System.Security.SecuritySafeCritical]  // auto-generated
         public EventWaitHandleSecurity GetAccessControl()
         {
             return new EventWaitHandleSecurity(safeWaitHandle, AccessControlSections.Access | AccessControlSections.Owner | AccessControlSections.Group);
         }
+#endif
 
+#if FEATURE_MACL
         [System.Security.SecuritySafeCritical]  // auto-generated
         public void SetAccessControl(EventWaitHandleSecurity eventSecurity)
         {
index b477f7bb686d3aa8758503ff45f1bce268e22855..d85cf9fb97643751787b80da2b208e0e89641c5c 100644 (file)
@@ -1081,7 +1081,6 @@ namespace System.Threading {
 
             dls.Store.SetData(slot, data);
         }
-#if !MONO
 
         // #threadCultureInfo
         //
@@ -1337,12 +1336,23 @@ namespace System.Threading {
         }
 
 #if! FEATURE_LEAK_CULTURE_INFO
+
+#if MONO
+        static void nativeInitCultureAccessors()
+        {
+            m_CurrentCulture = CultureInfo.ConstructCurrentCulture ();
+            m_CurrentUICulture = CultureInfo.ConstructCurrentUICulture ();
+        }
+#else
         [System.Security.SecurityCritical]  // auto-generated
         [ResourceExposure(ResourceScope.None)]
         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
         [SuppressUnmanagedCodeSecurity]
         private static extern void nativeInitCultureAccessors();
 #endif
+#endif
+
+#if !MONO
 
         /*=============================================================*/
 
diff --git a/mcs/errors/cs0246-36.cs b/mcs/errors/cs0246-36.cs
new file mode 100644 (file)
index 0000000..2bd3567
--- /dev/null
@@ -0,0 +1,9 @@
+// CS0246: The type or namespace name `Foo' could not be found. Are you missing an assembly reference?
+// Line: 8
+
+class Crashy
+{
+       void Call (System.Action<object> action) { }
+
+       public void DoCrash () => Call (f => f as Foo);
+}
index 01285712a2b3787590464510bc71d67f99167ed0..9c4b6a172a0175c6521e885fff4f1dc42dca5d1f 100644 (file)
@@ -68,10 +68,10 @@ btest: mcs2.exe mcs3.exe
        ls -l mcs2.exe mcs3.exe
 
 mcs2.exe: $(PROGRAM)
-       $(TIME) $(RUNTIME) $(RUNTIME_FLAGS) $(PROGRAM) $(USE_MCS_FLAGS) -target:exe -out:$@ $(BUILT_SOURCES) @$(response)
+       $(TIME) $(RUNTIME) $(RUNTIME_FLAGS) $(PROGRAM) $(USE_MCS_FLAGS) $(MCS_REFERENCES) -target:exe -out:$@ $(BUILT_SOURCES) $(EXTRA_SOURCES) @$(response)
 
 mcs3.exe: mcs2.exe
-       $(TIME) $(RUNTIME) $(RUNTIME_FLAGS) ./mcs2.exe $(USE_MCS_FLAGS) -target:exe -out:$@ $(BUILT_SOURCES) @$(response)
+       $(TIME) $(RUNTIME) $(RUNTIME_FLAGS) ./mcs2.exe $(USE_MCS_FLAGS) $(MCS_REFERENCES) -target:exe -out:$@ $(BUILT_SOURCES) $(EXTRA_SOURCES) @$(response)
 
 wc:
        wc -l $(BUILT_SOURCES) `cat $(sourcefile)`
index 80481ed2091f6ba2cf1deb7c25e4c5514ce9e529..d27fe806048797af33538b202c262e0e040dff4e 100644 (file)
@@ -1595,6 +1595,15 @@ namespace Mono.CSharp {
                        if (res && errors != ec.Report.Errors)
                                return null;
 
+                       if (block.IsAsync && block.Original.ParametersBlock.HasCapturedThis && ec.CurrentAnonymousMethod != null && ec.CurrentAnonymousMethod.block.IsAsync) {
+                               //
+                               // We'll do ldftn to load the fabricated m_X method but
+                               // because we are inside struct the method can be hoisted
+                               // anywhere in the parent scope
+                               //
+                               ec.CurrentBlock.ParametersBlock.HasReferenceToStoreyForInstanceLambdas = true;
+                       }
+
                        return res ? this : null;
                }
 
@@ -1798,6 +1807,8 @@ namespace Mono.CSharp {
                                                        parent = storey = sm;
                                                }
                                        }
+                               } else if (src_block.ParametersBlock.HasReferenceToStoreyForInstanceLambdas) {
+                                       src_block.ParametersBlock.StateMachine.AddParentStoreyReference (ec, storey);
                                }
 
                                modifiers = storey != null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
index 85dff2b3c84fcb71651275ea08fb316c379f9d64..318d040985aad465932a8ea66ed1cc53f92dc3dc 100644 (file)
@@ -45,18 +45,16 @@ namespace Mono.CSharp
                bool IsFriendAssemblyTo (IAssemblyDefinition assembly);
        }
 
-       public class AssemblyReferenceErrorInfo
+       public class AssemblyReferenceMessageInfo
        {
-               public AssemblyReferenceErrorInfo (AssemblyName dependencyName, string location, string message)
+               public AssemblyReferenceMessageInfo (AssemblyName dependencyName, Action<Report> reportMessage)
                {
                        this.DependencyName = dependencyName;
-                       this.RequestingAssemblyLocation = location;
-                       this.Message = message;
+                       this.ReportMessage = reportMessage;
                }
 
                public AssemblyName DependencyName { get; private set; }
-               public string RequestingAssemblyLocation { get; private set; }
-               public string Message { get; private set; }
+               public Action<Report> ReportMessage { get; private set; }
        }
                 
        public abstract class AssemblyDefinition : IAssemblyDefinition
@@ -456,8 +454,7 @@ namespace Mono.CSharp
                                                // due to type-forwarding
                                                //
                                                if (references.Any (l => l.Name == r.DependencyName.Name)) {
-                                                       Report.SymbolRelatedToPreviousError (r.RequestingAssemblyLocation);
-                                                       Report.Error (1705, r.Message);
+                                                       r.ReportMessage (Report);
                                                }
                                        }
                                }
@@ -592,7 +589,7 @@ namespace Mono.CSharp
                        return public_key_token;
                }
 
-               protected virtual List<AssemblyReferenceErrorInfo> GetNotUnifiedReferences (AssemblyName assemblyName)
+               protected virtual List<AssemblyReferenceMessageInfo> GetNotUnifiedReferences (AssemblyName assemblyName)
                {
                        return null;
                }
index 1c63e70b91d269a9f647f0505a8377731bbd0c98..1915a07240b379fdf4443385f6bd5a0af1e07783 100644 (file)
@@ -2562,6 +2562,9 @@ namespace Mono.CSharp
                                                                        pow /= 10;
                                                                }
                                                        }
+                                               } else if (c == '\n' || c == UnicodeLS || c == UnicodePS) {
+                                                       advance_line ();
+                                                       break;
                                                } else if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && c != '_') {
                                                        break;
                                                }
@@ -2587,9 +2590,6 @@ namespace Mono.CSharp
                                while (c == ' ' || c == '\t')
                                        c = get_char ();
 
-                               if (c == '\n' || c == UnicodeLS || c == UnicodePS)
-                                       advance_line ();
-
                                return number;
                        }
 
index 02ae36b34c16802d921a2476f4a1ab3d750052c3..2a9aa97fed0e62be46728b7c4dccb871de0ff0cc 100644 (file)
@@ -2362,6 +2362,11 @@ namespace Mono.CSharp
                        eclass = ExprClass.Value;
                        TypeSpec etype = expr.Type;
 
+                       if (type == null) {
+                               type = InternalType.ErrorType;
+                               return this;
+                       }
+
                        if (!TypeSpec.IsReferenceType (type) && !type.IsNullableType) {
                                if (TypeManager.IsGenericParameter (type)) {
                                        ec.Report.Error (413, loc,
index f4b9930f3999e8c3395d53a4319744d1130492c0..17dc6f8817627126ab4fcd9d4f39b3f1dcd9fd88 100644 (file)
@@ -220,7 +220,7 @@ namespace Mono.CSharp
                        return Builder.__AddModule (moduleFile);
                }
 
-               protected override List<AssemblyReferenceErrorInfo> GetNotUnifiedReferences (AssemblyName assemblyName)
+               protected override List<AssemblyReferenceMessageInfo> GetNotUnifiedReferences (AssemblyName assemblyName)
                {
                        return loader.GetNotUnifiedReferences (assemblyName);
                }
@@ -238,7 +238,7 @@ namespace Mono.CSharp
                Assembly corlib;
                readonly List<Tuple<AssemblyName, string, Assembly>> loaded_names;
                static readonly Dictionary<string, string[]> sdk_directory;
-               Dictionary<AssemblyName, List<AssemblyReferenceErrorInfo>> resolved_version_mismatches;
+               Dictionary<AssemblyName, List<AssemblyReferenceMessageInfo>> resolved_version_mismatches;
                static readonly TypeName objectTypeName = new TypeName ("System", "Object");
 
                static StaticLoader ()
@@ -364,33 +364,30 @@ namespace Mono.CSharp
                                var v2 = version_mismatch.GetName ().Version;
 
                                if (v1 > v2) {
-                                       if (resolved_version_mismatches == null)
-                                               resolved_version_mismatches = new Dictionary<AssemblyName, List<AssemblyReferenceErrorInfo>> ();
-
-                                       var an = args.RequestingAssembly.GetName ();
-                                       List<AssemblyReferenceErrorInfo> names;
-                                       if (!resolved_version_mismatches.TryGetValue (an, out names)) {
-                                               names = new List<AssemblyReferenceErrorInfo> ();
-                                               resolved_version_mismatches.Add (an, names);
-                                       }
-
-                                       names.Add (new AssemblyReferenceErrorInfo (ref_an, args.RequestingAssembly.Location,
-                                               string.Format ("Assembly `{0}' depends on `{1}' which has a higher version number than referenced assembly `{2}'",
-                                                          args.RequestingAssembly.FullName, refname, version_mismatch.GetName ().FullName)));
+                                       var messageInfo = new AssemblyReferenceMessageInfo (ref_an, report => {
+                                               report.SymbolRelatedToPreviousError (args.RequestingAssembly.Location);
+                                               report.Error (1705, string.Format ("Assembly `{0}' depends on `{1}' which has a higher version number than referenced assembly `{2}'",
+                                                                                                                  args.RequestingAssembly.FullName, refname, version_mismatch.GetName ().FullName));
+                                       });
 
+                                       AddReferenceVersionMismatch (args.RequestingAssembly.GetName (), messageInfo);
                                        return version_mismatch;
                                }
 
                                if (!is_fx_assembly) {
-                                       if (v1.Major != v2.Major || v1.Minor != v2.Minor) {
-                                               compiler.Report.Warning (1701, 2,
-                                                       "Assuming assembly reference `{0}' matches assembly `{1}'. You may need to supply runtime policy",
-                                                       refname, version_mismatch.GetName ().FullName);
-                                       } else {
-                                               compiler.Report.Warning (1702, 3,
-                                                       "Assuming assembly reference `{0}' matches assembly `{1}'. You may need to supply runtime policy",
-                                                       refname, version_mismatch.GetName ().FullName);
-                                       }
+                                       var messageInfo = new AssemblyReferenceMessageInfo (ref_an, report => {
+                                               if (v1.Major != v2.Major || v1.Minor != v2.Minor) {
+                                                       report.Warning (1701, 2,
+                                                               "Assuming assembly reference `{0}' matches assembly `{1}'. You may need to supply runtime policy",
+                                                               refname, version_mismatch.GetName ().FullName);
+                                               } else {
+                                                       report.Warning (1702, 3,
+                                                               "Assuming assembly reference `{0}' matches assembly `{1}'. You may need to supply runtime policy",
+                                                               refname, version_mismatch.GetName ().FullName);
+                                               }
+                                       });
+
+                                       AddReferenceVersionMismatch (args.RequestingAssembly.GetName (), messageInfo);
                                }
 
                                return version_mismatch;
@@ -409,6 +406,20 @@ namespace Mono.CSharp
                        return domain.CreateMissingAssembly (args.Name);
                }
 
+               void AddReferenceVersionMismatch (AssemblyName an, AssemblyReferenceMessageInfo errorInfo)
+               {
+                       if (resolved_version_mismatches == null)
+                               resolved_version_mismatches = new Dictionary<AssemblyName, List<AssemblyReferenceMessageInfo>> ();
+
+                       List<AssemblyReferenceMessageInfo> names;
+                       if (!resolved_version_mismatches.TryGetValue (an, out names)) {
+                               names = new List<AssemblyReferenceMessageInfo> ();
+                               resolved_version_mismatches.Add (an, names);
+                       }
+
+                       names.Add (errorInfo);
+               }
+
                public void Dispose ()
                {
                        domain.Dispose ();
@@ -433,9 +444,9 @@ namespace Mono.CSharp
                        return default_references.ToArray ();
                }
 
-               public List<AssemblyReferenceErrorInfo> GetNotUnifiedReferences (AssemblyName assemblyName)
+               public List<AssemblyReferenceMessageInfo> GetNotUnifiedReferences (AssemblyName assemblyName)
                {
-                       List<AssemblyReferenceErrorInfo> list = null;
+                       List<AssemblyReferenceMessageInfo> list = null;
                        if (resolved_version_mismatches != null)
                                resolved_version_mismatches.TryGetValue (assemblyName, out list);
 
index ad08d02b5db754d3948bdb8ad9c4b690011c1aff..7f54b33eeb599c16146c7adfcc0c2e12b3d5beaf 100644 (file)
@@ -2657,6 +2657,7 @@ namespace Mono.CSharp {
                        AwaitBlock = 1 << 13,
                        FinallyBlock = 1 << 14,
                        CatchBlock = 1 << 15,
+                       HasReferenceToStoreyForInstanceLambdas = 1 << 16,
                        Iterator = 1 << 20,
                        NoFlowAnalysis = 1 << 21,
                        InitializationEmitted = 1 << 22
@@ -3281,7 +3282,7 @@ namespace Mono.CSharp {
                                                        break;
                                        }
                                }
-                               
+
                                //
                                // We are the first storey on path and 'this' has to be hoisted
                                //
@@ -3349,7 +3350,7 @@ namespace Mono.CSharp {
 
                                                                //
                                                                // If we are state machine with no parent. We can hook into parent without additional
-                                                               // reference and capture this directly
+                                                               // reference and capture this directly
                                                                //
                                                                ExplicitBlock parent_storey_block = pb;
                                                                while (parent_storey_block.Parent != null) {
@@ -3666,6 +3667,15 @@ namespace Mono.CSharp {
 
                #region Properties
 
+               public bool HasReferenceToStoreyForInstanceLambdas {
+                       get {
+                               return (flags & Flags.HasReferenceToStoreyForInstanceLambdas) != 0;
+                       }
+                       set {
+                               flags = value ? flags | Flags.HasReferenceToStoreyForInstanceLambdas : flags & ~Flags.HasReferenceToStoreyForInstanceLambdas;
+                       }
+               }
+
                public bool IsAsync {
                        get {
                                return (flags & Flags.HasAsyncModifier) != 0;
@@ -6002,7 +6012,7 @@ namespace Mono.CSharp {
                                ec.EmitInt (first_resume_pc);
                                ec.Emit (OpCodes.Sub);
 
-                               var labels = new Label[resume_points.Count - System.Math.Max (first_catch_resume_pc, 0)];
+                               var labels = new Label [first_catch_resume_pc > 0 ? first_catch_resume_pc : resume_points.Count];
                                for (int i = 0; i < labels.Length; ++i)
                                        labels[i] = resume_points[i].PrepareForEmit (ec);
                                ec.Emit (OpCodes.Switch, labels);
diff --git a/mcs/tests/dtest-065.cs b/mcs/tests/dtest-065.cs
new file mode 100644 (file)
index 0000000..fb51a71
--- /dev/null
@@ -0,0 +1,28 @@
+using System.Dynamic;
+
+public class TestConvert : DynamicObject
+{
+       public override bool TryConvert (ConvertBinder binder, out object result)
+       {
+               result = null;
+               return true;
+       }
+}
+
+public class Test : DynamicObject
+{
+       public override bool TryInvokeMember (InvokeMemberBinder binder, object [] args, out object result)
+       {
+               result = new TestConvert ();
+               return true;
+       }
+}
+
+public class XX
+{
+       public static void Main ()
+       {
+               dynamic t = new Test ();
+               string result = t.SomeMethod ();
+       }
+}
\ No newline at end of file
diff --git a/mcs/tests/test-async-88.cs b/mcs/tests/test-async-88.cs
new file mode 100644 (file)
index 0000000..813d51d
--- /dev/null
@@ -0,0 +1,28 @@
+using System;
+using System.Threading.Tasks;
+
+public class Test
+{
+       static async Task<string> AsyncWithDeepTry ()
+       {
+               try {
+                       await Task.Yield ();
+
+                       try {
+                               await Task.Yield ();
+                       } catch {
+                       }
+               } catch {
+                       await Task.Yield ();
+               } finally {
+               }
+
+               return null;
+       }
+
+
+       static void Main ()
+       {
+               AsyncWithDeepTry ().Wait ();
+       }
+}
diff --git a/mcs/tests/test-async-89.cs b/mcs/tests/test-async-89.cs
new file mode 100644 (file)
index 0000000..5a69685
--- /dev/null
@@ -0,0 +1,51 @@
+using System;
+using System.Threading.Tasks;
+
+class X
+{
+       public static void Main ()
+       {
+               new X ().Test ();
+       }
+
+       void Test ()
+       {
+               object v1 = null;
+
+               Action a = () =>
+               {
+                       if (v1 == null)
+                       {
+                               object v2 = null;
+
+                               Action a2 = () =>
+                               {
+                                       Console.WriteLine (v2);
+                               };
+                               
+                               Action a3 = async () =>
+                               {
+                                       // This scope needs to access to Scope which can do ldftn on instance method
+                                       {
+                                       Func<Task> a4 = async () =>
+                                       {
+                                               await Foo ();
+                                       };
+                                       }
+
+                                       await Task.Yield ();
+                               };
+
+                               a3 ();
+                       }
+               };
+
+               a ();
+       }
+
+       async Task Foo ()
+       {
+               await Task.FromResult (1);
+       }
+
+}
\ No newline at end of file
index 461f6573e595c09f20e31b96fea3787550c331a1..34ed22655308b7fe7348feac6132a032a4b21206 100644 (file)
@@ -1,7 +1,7 @@
 ï»¿<?xml version="1.0" encoding="utf-8"?>
 <symbols>
   <files>
-    <file id="1" name="test-debug-30.cs" checksum="d3addfa69f16faf00991ef839451a975" />
+    <file id="1" name="test-debug-30.cs" checksum="5303b32b0208123737567d53022ae3d5" />
   </files>
   <methods>
     <method token="0x6000001">
       <locals />
       <scopes />
     </method>
+    <method token="0x6000004">
+      <sequencepoints>
+        <entry il="0x0" row="23" col="2" file_ref="1" hidden="false" />
+        <entry il="0x1" row="24" col="3" file_ref="1" hidden="false" />
+        <entry il="0x6" row="25" col="2" file_ref="1" hidden="false" />
+      </sequencepoints>
+      <locals />
+      <scopes />
+    </method>
   </methods>
 </symbols>
\ No newline at end of file
index 78f0cdfe3c74a9e6b6631ef20e0e6e0616c577e7..a72f014101ee2392d3d532080ee712a51d06158c 100644 (file)
@@ -15,4 +15,12 @@ class PragmaNewLinesParsing
        {
                return;
        }
+
+#pragma warning disable 618
+#pragma warning restore 618
+
+       void OneMore ()
+       {
+               return;
+       }
 }
\ No newline at end of file
index a95de56e90c17e519bd041af1030ecd6cab58c3e..67147f16a7725c577a9bc49dba24b87f69d56296 100644 (file)
       </method>
     </type>
   </test>
+  <test name="dtest-065.cs">
+    <type name="TestConvert">
+      <method name="Boolean TryConvert(System.Dynamic.ConvertBinder, System.Object ByRef)" attrs="198">
+        <size>13</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Test">
+      <method name="Boolean TryInvokeMember(System.Dynamic.InvokeMemberBinder, System.Object[], System.Object ByRef)" attrs="198">
+        <size>17</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="XX">
+      <method name="Void Main()" attrs="150">
+        <size>154</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="dtest-anontype-01.cs">
     <type name="C">
       <method name="Void Main()" attrs="150">
       </method>
     </type>
   </test>
+  <test name="test-async-88.cs">
+    <type name="Test">
+      <method name="System.Threading.Tasks.Task`1[System.String] AsyncWithDeepTry()" attrs="145">
+        <size>33</size>
+      </method>
+      <method name="Void Main()" attrs="145">
+        <size>12</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Test+&lt;AsyncWithDeepTry&gt;c__async0">
+      <method name="Void MoveNext()" attrs="486">
+        <size>460</size>
+      </method>
+      <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+  </test>
+  <test name="test-async-89.cs">
+    <type name="X">
+      <method name="Void Main()" attrs="150">
+        <size>12</size>
+      </method>
+      <method name="Void Test()" attrs="129">
+        <size>41</size>
+      </method>
+      <method name="System.Threading.Tasks.Task Foo()" attrs="129">
+        <size>33</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="X+&lt;Test&gt;c__AnonStorey1">
+      <method name="Void &lt;&gt;m__0()" attrs="131">
+        <size>67</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="X+&lt;Foo&gt;c__async0">
+      <method name="Void MoveNext()" attrs="486">
+        <size>158</size>
+      </method>
+      <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+    <type name="X+&lt;Test&gt;c__AnonStorey1+&lt;Test&gt;c__AnonStorey2">
+      <method name="Void &lt;&gt;m__0()" attrs="131">
+        <size>13</size>
+      </method>
+      <method name="Void &lt;&gt;m__1()" attrs="131">
+        <size>48</size>
+      </method>
+      <method name="System.Threading.Tasks.Task &lt;&gt;m__2()" attrs="131">
+        <size>46</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="X+&lt;Test&gt;c__AnonStorey1+&lt;Test&gt;c__AnonStorey2+&lt;Test&gt;c__async3">
+      <method name="Void MoveNext()" attrs="486">
+        <size>179</size>
+      </method>
+      <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+    <type name="X+&lt;Test&gt;c__AnonStorey1+&lt;Test&gt;c__AnonStorey2+&lt;Test&gt;c__async4">
+      <method name="Void MoveNext()" attrs="486">
+        <size>167</size>
+      </method>
+      <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+  </test>
   <test name="test-cls-00.cs">
     <type name="CLSCLass_6">
       <method name="Void add_Disposed(Delegate)" attrs="2182">
       <method name="Void .ctor()" attrs="6278">
         <size>7</size>
       </method>
+      <method name="Void OneMore()" attrs="129">
+        <size>7</size>
+      </method>
     </type>
   </test>
   <test name="test-decl-expr-01.cs">
index bdc741144ea595cb7d7bcbeb8b509e5a3e225148..3670d2f2eb94c6562db2a34b84eb5653165e4c07 100644 (file)
@@ -13,14 +13,13 @@ using System.Globalization;
 using System.IO;
 using System.Collections;
 using System.Collections.Generic;
-using System.Reflection;
-using System.Reflection.Emit;
 using System.Security.Cryptography;
 using System.Text;
 using System.Configuration.Assemblies;
 
+using IKVM.Reflection;
+using IKVM.Reflection.Emit;
 using Mono.Security.Cryptography;
-using IKR = IKVM.Reflection;
 
 namespace Mono.AssemblyLinker
 {
@@ -49,6 +48,15 @@ namespace Mono.AssemblyLinker
                No
        }
 
+       public enum Platform {
+               AnyCPU,
+               AnyCPU32Preferred,
+               Arm,
+               X86,
+               X64,
+               IA64
+       }
+
        public class AssemblyLinker {
 
                ArrayList inputFiles = new ArrayList ();
@@ -59,24 +67,35 @@ namespace Mono.AssemblyLinker
                string entryPoint;
                string win32IconFile;
                string win32ResFile;
+               string title;
+               string description;
+               string company;
+               string product;
+               string copyright;
+               string trademark;
                string templateFile;
                bool isTemplateFile = false;
                Target target = Target.Dll;
+               Platform platform = Platform.AnyCPU;
                DelaySign delaysign = DelaySign.NotSet;
                string keyfile;
                string keyname;
                string culture;
+               Universe universe;
 
                public static int Main (String[] args) {
                        return new AssemblyLinker ().DynMain (args);
                }
 
                private int DynMain (String[] args) {
-                       ParseArgs (args);
+                       using (universe = new Universe (UniverseOptions.MetadataOnly)) {
+                               universe.LoadFile (typeof (object).Assembly.Location);
+                               ParseArgs (args);
 
-                       DoIt ();
+                               DoIt ();
 
-                       return 0;
+                               return 0;
+                       }
                }
 
                private void ParseArgs (string[] args) 
@@ -211,7 +230,7 @@ namespace Mono.AssemblyLinker
                                        if (realArg.StartsWith ("0x"))
                                                realArg = realArg.Substring (2);
                                        uint val = Convert.ToUInt32 (realArg, 16);
-                                       AddCattr (typeof (AssemblyAlgorithmIdAttribute), typeof (uint), val);
+                                       AddCattr (typeof (System.Reflection.AssemblyAlgorithmIdAttribute), typeof (uint), val);
                                } catch (Exception) {
                                        ReportInvalidArgument (opt, arg);
                                }
@@ -233,21 +252,21 @@ namespace Mono.AssemblyLinker
                        case "company":
                                if (arg == null)
                                        ReportMissingText (opt);
-                               AddCattr (typeof (AssemblyCompanyAttribute), arg);
+                               company = arg;
                                return true;
 
                        case "config":
                        case "configuration":
                                if (arg == null)
                                        ReportMissingText (opt);
-                               AddCattr (typeof (AssemblyConfigurationAttribute), arg);
+                               AddCattr (typeof (System.Reflection.AssemblyConfigurationAttribute), arg);
                                return true;
 
                        case "copy":
                        case "copyright":
                                if (arg == null)
                                        ReportMissingText (opt);
-                               AddCattr (typeof (AssemblyCopyrightAttribute), arg);
+                               copyright = arg;
                                return true;
 
                        case "c":
@@ -273,7 +292,7 @@ namespace Mono.AssemblyLinker
                        case "description":
                                if (arg == null)
                                        ReportMissingText (opt);
-                               AddCattr (typeof (AssemblyDescriptionAttribute), arg);
+                               description = arg;
                                return true;
 
                        case "e":
@@ -292,7 +311,7 @@ namespace Mono.AssemblyLinker
                                if (arg == null)
                                        ReportMissingText (opt);
 
-                               AddCattr (typeof (AssemblyFileVersionAttribute), arg);
+                               AddCattr (typeof (System.Reflection.AssemblyFileVersionAttribute), arg);
                                return true;
 
                        case "flags":
@@ -303,7 +322,7 @@ namespace Mono.AssemblyLinker
                                        if (realArg.StartsWith ("0x"))
                                                realArg = realArg.Substring (2);
                                        uint val = Convert.ToUInt32 (realArg, 16);
-                                       AddCattr (typeof (AssemblyFlagsAttribute), typeof (uint), val);
+                                       AddCattr (typeof (System.Reflection.AssemblyFlagsAttribute), typeof (uint), val);
                                } catch (Exception) {
                                        ReportInvalidArgument (opt, arg);
                                }
@@ -342,18 +361,46 @@ namespace Mono.AssemblyLinker
                                outFile = arg;
                                return true;
 
+               case "platform":
+                       if (arg == null)
+                               ReportMissingText (opt);
+                       switch (arg.ToLowerInvariant ()) {
+                               case "arm":
+                                       platform = Platform.Arm;
+                                       break;
+                               case "anycpu":
+                                       platform = Platform.AnyCPU;
+                                       break;
+                               case "x86":
+                                       platform = Platform.X86;
+                                       break;
+                               case "x64":
+                                       platform = Platform.X64;
+                                       break;
+                               case "itanium":
+                                       platform = Platform.IA64;
+                                       break;
+                               case "anycpu32bitpreferred":
+                                       platform = Platform.AnyCPU32Preferred;
+                                       break;
+                               default:
+                                       ReportInvalidArgument (opt, arg);
+                                       break;
+                               }
+                               return true;
+
                        case "prod":
                        case "product":
                                if (arg == null)
                                        ReportMissingText (opt);
-                               AddCattr (typeof (AssemblyProductAttribute), arg);
+                               product = arg;
                                return true;
 
                        case "productv":
                        case "productversion":
                                if (arg == null)
                                        ReportMissingText (opt);
-                               AddCattr (typeof (AssemblyInformationalVersionAttribute), arg);
+                               AddCattr (typeof (System.Reflection.AssemblyInformationalVersionAttribute), arg);
                                return true;
 
                        case "t":
@@ -388,14 +435,14 @@ namespace Mono.AssemblyLinker
                        case "title":
                                if (arg == null)
                                        ReportMissingText (opt);
-                               AddCattr (typeof (AssemblyTitleAttribute), arg);
+                               title = arg;
                                return true;
 
                        case "trade":
                        case "trademark":
                                if (arg == null)
                                        ReportMissingText (opt);
-                               AddCattr (typeof (AssemblyTrademarkAttribute), arg);
+                               trademark = arg;
                                return true;
 
                        case "v":
@@ -405,7 +452,7 @@ namespace Mono.AssemblyLinker
                                        Version ();
                                        break;
                                }
-                               AddCattr (typeof (AssemblyVersionAttribute), arg);
+                               AddCattr (typeof (System.Reflection.AssemblyVersionAttribute), arg);
                                return true;
 
                        case "win32icon":
@@ -461,11 +508,14 @@ namespace Mono.AssemblyLinker
                        return command.ToLower ();
                }
 
-               private void AddCattr (Type attrType, Type arg, object value) {
-                       cattrs.Add (new CustomAttributeBuilder (attrType.GetConstructor (new Type [] { arg }), new object [] { value }));
+               private void AddCattr (System.Type attrType, System.Type arg, object value) {
+                       var importedAttrType = universe.Import(attrType);
+                       var importedArg = universe.Import(arg);
+
+                       cattrs.Add (new CustomAttributeBuilder (importedAttrType.GetConstructor (new [] { importedArg }), new [] { value }));
                }
 
-               private void AddCattr (Type attrType, object value) {
+               private void AddCattr (System.Type attrType, object value) {
                        AddCattr (attrType, typeof (string), value);
                }
 
@@ -596,12 +646,25 @@ namespace Mono.AssemblyLinker
                        if (isTemplateFile)
                                aname = ReadCustomAttributesFromTemplateFile (templateFile, aname);
 
+                       if (!String.IsNullOrEmpty (title))
+                               AddCattr (typeof (System.Reflection.AssemblyTitleAttribute), title);
+                       if (!String.IsNullOrEmpty (description))
+                               AddCattr (typeof (System.Reflection.AssemblyDescriptionAttribute), description);
+                       if (!String.IsNullOrEmpty (company))
+                               AddCattr (typeof (System.Reflection.AssemblyCompanyAttribute), company);
+                       if (!String.IsNullOrEmpty (product))
+                               AddCattr (typeof (System.Reflection.AssemblyProductAttribute), product);
+                       if (!String.IsNullOrEmpty (copyright))
+                               AddCattr (typeof (System.Reflection.AssemblyCopyrightAttribute), copyright);
+                       if (!String.IsNullOrEmpty (trademark))
+                               AddCattr (typeof (System.Reflection.AssemblyTrademarkAttribute), trademark);
+
                        SetKeyPair (aname);
 
                        if (fileName != outFile)
-                               ab = AppDomain.CurrentDomain.DefineDynamicAssembly (aname, AssemblyBuilderAccess.Save, Path.GetDirectoryName (outFile));
+                               ab = universe.DefineDynamicAssembly (aname, AssemblyBuilderAccess.Save, Path.GetDirectoryName (outFile));
                        else
-                               ab = AppDomain.CurrentDomain.DefineDynamicAssembly (aname, AssemblyBuilderAccess.Save);
+                               ab = universe.DefineDynamicAssembly (aname, AssemblyBuilderAccess.Save);
 
                        foreach (CustomAttributeBuilder cb in cattrs)
                                ab.SetCustomAttribute (cb);
@@ -611,10 +674,6 @@ namespace Mono.AssemblyLinker
                         */
 
                        foreach (ModuleInfo mod in inputFiles) {
-                               MethodInfo mi = typeof (AssemblyBuilder).GetMethod ("AddModule", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
-                               if (mi == null)
-                                       Report (0, "Cannot add modules on this runtime: try the Mono runtime instead.");
-
                                if (mod.target != null) {
                                        File.Copy (mod.fileName, mod.target, true);
                                        mod.fileName = mod.target;
@@ -631,7 +690,7 @@ namespace Mono.AssemblyLinker
                                if (isAssembly)
                                        ReportWarning (1020, "Ignoring included assembly '" + mod.fileName + "'");
                                else
-                                       mi.Invoke (ab, new object [] { mod.fileName });
+                               ab.__AddModule (universe.OpenRawModule(mod.fileName));
                        }
 
                        /*
@@ -645,7 +704,7 @@ namespace Mono.AssemblyLinker
                                MethodInfo mainMethodInfo = null;
 
                                try {
-                                       Type mainType = ab.GetType (mainClass);
+                                       IKVM.Reflection.Type mainType = ab.GetType (mainClass);
                                        if (mainType != null)
                                                mainMethodInfo = mainType.GetMethod (mainMethod);
                                }
@@ -666,10 +725,7 @@ namespace Mono.AssemblyLinker
 
                        if (win32IconFile != null) {
                                try {
-                                       MethodInfo mi = typeof (AssemblyBuilder).GetMethod ("DefineIconResource", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
-                                       if (mi == null)
-                                               Report (0, "Cannot embed win32 icons on this runtime: try the Mono runtime instead.");
-                                       mi.Invoke (ab, new object [] {  win32IconFile });
+                                       ab.__DefineIconResource (File.ReadAllBytes (win32IconFile));
                                }
                                catch (Exception ex) {
                                        Report (1031, "Error reading icon '" + win32IconFile + "' --" + ex);
@@ -685,6 +741,8 @@ namespace Mono.AssemblyLinker
                                }
                        }
 
+                       ModuleBuilder mainModule = null;
+
                        foreach (ResourceInfo res in resources) {
                                if (res.name == null)
                                        res.name = Path.GetFileName (res.fileName);
@@ -694,11 +752,13 @@ namespace Mono.AssemblyLinker
                                                Report (1046, String.Format ("Resource identifier '{0}' has already been used in this assembly", res.name));
 
                                if (res.isEmbedded) {
-                                       MethodInfo mi = typeof (AssemblyBuilder).GetMethod ("EmbedResourceFile", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic,
-                                               null, CallingConventions.Any, new Type [] { typeof (string), typeof (string) }, null);
-                                       if (mi == null)
-                                               Report (0, "Cannot embed resources on this runtime: try the Mono runtime instead.");
-                                       mi.Invoke (ab, new object [] { res.name, res.fileName });
+                                       if (mainModule == null) {
+                                               mainModule = ab.DefineDynamicModule (fileName, fileName, false);
+                                       }
+
+                                       Stream stream = new MemoryStream (File.ReadAllBytes (res.fileName));
+
+                                       mainModule.DefineManifestResource (res.name, stream, res.isPrivate ? ResourceAttributes.Private : ResourceAttributes.Public);
                                }
                                else {
                                        if (res.target != null) {
@@ -721,8 +781,36 @@ namespace Mono.AssemblyLinker
                                }
                        }
 
+                       PortableExecutableKinds pekind = PortableExecutableKinds.ILOnly;
+                       ImageFileMachine machine;
+
+                       switch (platform) {
+                       case Platform.X86:
+                               pekind |= PortableExecutableKinds.Required32Bit;
+                               machine = ImageFileMachine.I386;
+                               break;
+                       case Platform.X64:
+                               pekind |= PortableExecutableKinds.PE32Plus;
+                               machine = ImageFileMachine.AMD64;
+                               break;
+                       case Platform.IA64:
+                               machine = ImageFileMachine.IA64;
+                               break;
+                       case Platform.AnyCPU32Preferred:
+                               pekind |= PortableExecutableKinds.Preferred32Bit;
+                               machine = ImageFileMachine.I386;
+                               break;
+                       case Platform.Arm:
+                               machine = ImageFileMachine.ARM;
+                               break;
+                       case Platform.AnyCPU:
+                       default:
+                               machine = ImageFileMachine.I386;
+                               break;
+                       }
+
                        try {
-                               ab.Save (fileName);
+                               ab.Save (fileName, pekind, machine);
                        }
                        catch (Exception ex) {
                                Report (1019, "Metadata failure creating assembly -- " + ex);
@@ -733,17 +821,14 @@ namespace Mono.AssemblyLinker
                {
                        // LAMESPEC: according to MSDN, the template assembly must have a
                        // strong name but this is not enforced
-                       const IKR.UniverseOptions options = IKR.UniverseOptions.MetadataOnly;
-
-                       var universe = new IKR.Universe (options);
                        var asm = universe.LoadFile (templateFile);
 
                        // Create missing assemblies, we don't want to load them!
                        // Code taken from ikdasm
                        var names = new HashSet<string> ();
-                       IKR.AssemblyName[] assembly_refs = asm.ManifestModule.__GetReferencedAssemblies ();
+                       AssemblyName[] assembly_refs = asm.ManifestModule.__GetReferencedAssemblies ();
 
-                       var resolved_assemblies = new IKR.Assembly [assembly_refs.Length];
+                       var resolved_assemblies = new Assembly [assembly_refs.Length];
                        for (int i = 0; i < resolved_assemblies.Length; i++) {
                                string name = assembly_refs [i].Name;
 
@@ -798,6 +883,85 @@ namespace Mono.AssemblyLinker
                                                        keyname = key_name_value;
                                        }
                                        break;
+
+                                       case "System.Reflection.AssemblyTitleAttribute": {
+                                               if (title != null)
+                                                       // ignore if specified on command line
+                                                       continue;
+
+                                               // AssemblyTitleAttribute .ctor(string title)
+                                               string title_value = (string) attr_data.ConstructorArguments [0].Value;
+
+                                               if (!String.IsNullOrEmpty (title_value))
+                                                       title = title_value;
+                                       }
+                                       break;
+
+                                       case "System.Reflection.AssemblyDescriptionAttribute": {
+                                               if (description != null)
+                                                       // ignore if specified on command line
+                                                       continue;
+
+                                               // AssemblyDescriptionAttribute .ctor(string description)
+                                               string description_value = (string) attr_data.ConstructorArguments [0].Value;
+
+                                               if (!String.IsNullOrEmpty (description_value))
+                                                       description = description_value;
+                                       }
+                                       break;
+
+                                       case "System.Reflection.AssemblyProductAttribute": {
+                                               if (product != null)
+                                                       // ignore if specified on command line
+                                                       continue;
+
+                                               // AssemblyProductAttribute .ctor(string product)
+                                               string product_value = (string) attr_data.ConstructorArguments [0].Value;
+
+                                               if (!String.IsNullOrEmpty (product_value))
+                                                       product = product_value;
+                                       }
+                                       break;
+
+                                       case "System.Reflection.AssemblyCompanyAttribute": {
+                                               if (company != null)
+                                                       // ignore if specified on command line
+                                                       continue;
+
+                                               // AssemblyCompanyAttribute .ctor(string company)
+                                               string company_value = (string) attr_data.ConstructorArguments [0].Value;
+
+                                               if (!String.IsNullOrEmpty (company_value))
+                                                       company = company_value;
+
+                                       }
+                                       break;
+
+                                       case "System.Reflection.AssemblyCopyrightAttribute": {
+                                               if (copyright != null)
+                                                       // ignore if specified on command line
+                                                       continue;
+
+                                               // AssemblyCopyrightAttribute .ctor(string copyright)
+                                               string copyright_value = (string) attr_data.ConstructorArguments [0].Value;
+
+                                               if (!String.IsNullOrEmpty (copyright_value))
+                                                       copyright = copyright_value;
+                                       }
+                                       break;
+
+                                       case "System.Reflection.AssemblyTrademarkAttribute": {
+                                               if (trademark != null)
+                                                       // ignore if specified on command line
+                                                       continue;
+
+                                               // AssemblyTrademarkAttribute .ctor(string trademark)
+                                               string trademark_value = (string) attr_data.ConstructorArguments [0].Value;
+
+                                               if (!String.IsNullOrEmpty (trademark_value))
+                                                       trademark = trademark_value;
+                                       }
+                                       break;
                                }
                        }
 
@@ -877,6 +1041,9 @@ namespace Mono.AssemblyLinker
                        "  /main:<method>            Specifies the method name of the entry point",
                        "  /nologo                   Suppress the startup banner and copyright message",
                        "  /out:<filename>           Output file name for the assembly manifest",
+                       "  /platform:<text>          Limit which platforms this code can run on; must be",
+                       "                            one of x86, Itanium, x64, arm, anycpu32bitpreferred,",
+                       "                            or anycpu (the default)",
                        "  /prod[uct]:<text>         Product name",
                        "  /productv[ersion]:<text>  Product version",
                        "  /t[arget]:lib[rary]       Create a library",
index 0e665fe7f5b0149ad30c17a21bec4e1ce8d54405..7636c2b204f4e6ed8cfc300f30bbe2ccca2e6268 100644 (file)
@@ -1089,9 +1089,12 @@ namespace CorCompare
                        if (!(memberDefenition is MethodDefinition))
                                return;
 
-                       MethodDefinition mbase = (MethodDefinition) memberDefenition;
+                       MethodDefinition mbase = (MethodDefinition)memberDefenition;
+
+                       ParameterData parms = new ParameterData (writer, mbase.Parameters) {
+                               HasExtensionParameter = mbase.CustomAttributes.Any (l => l.AttributeType.FullName == "System.Runtime.CompilerServices.ExtensionAttribute")
+                       };
 
-                       ParameterData parms = new ParameterData (writer, mbase.Parameters);
                        parms.DoOutput ();
 
                        MemberData.OutputGenericParameters (writer, mbase);
@@ -1137,8 +1140,11 @@ namespace CorCompare
                        this.parameters = parameters;
                }
 
+               public bool HasExtensionParameter { get; set; }
+
                public override void DoOutput ()
                {
+                       bool first = true;
                        writer.WriteStartElement ("parameters");
                        foreach (ParameterDefinition parameter in parameters) {
                                writer.WriteStartElement ("parameter");
@@ -1146,7 +1152,8 @@ namespace CorCompare
                                AddAttribute ("position", parameter.Method.Parameters.IndexOf(parameter).ToString(CultureInfo.InvariantCulture));
                                AddAttribute ("attrib", ((int) parameter.Attributes).ToString());
 
-                               string direction = "in";
+                               string direction = first && HasExtensionParameter ? "this" : "in";
+                               first = false;
 
                                if (parameter.ParameterType is ByReferenceType)
                                        direction = parameter.IsOut ? "out" : "ref";
index 0260c892e99b74494f18250b4979bf3c20fbff4c..0ae94deef202d9affd272d7269621be5ba6df058 100644 (file)
@@ -129,7 +129,7 @@ namespace Mono.Linker.Steps {
 
                static FileInfo GetOriginalAssemblyFileInfo (AssemblyDefinition assembly)
                {
-                       return new FileInfo (assembly.MainModule.FullyQualifiedName);
+                       return new FileInfo (assembly.MainModule.FileName);
                }
 
                static void CopyAssembly (FileInfo fi, string directory, bool symbols)
index 5e9f681fd1784d25dfd201c93fc913c409c6fa9f..aa4f6afc760388c38a5f1267ab4f2aa69f9ce473 100644 (file)
@@ -174,6 +174,14 @@ namespace Mono.Linker.Steps {
 
                        Annotations.Mark (type);
 
+                       if (type.IsNested) {
+                               var parent = type;
+                               while (parent.IsNested) {
+                                       parent = parent.DeclaringType;
+                                       Annotations.Mark (parent);
+                               }
+                       }
+
                        switch (preserve) {
                        case TypePreserve.Nothing:
                                if (!nav.HasChildren)
index e463ff9cde8d982212c5ead62160b37ef461cb7b..73c89cc7991f9c770da19dce0a6fa69deb7474e4 100644 (file)
@@ -152,7 +152,7 @@ namespace Mono.Linker.Steps {
                                // at this stage reference might include things that can't be resolved
                                // and if it is (resolved) it needs to be kept only if marked (#16213)
                                if ((td != null) && Annotations.IsMarked (td)) {
-                                       scope = assembly.MainModule.Import (td).Scope;
+                                       scope = assembly.MainModule.ImportReference (td).Scope;
                                        if (tr.Scope != scope)
                                                changes = true;
                                        hash.Add (tr, scope);
@@ -163,7 +163,7 @@ namespace Mono.Linker.Steps {
                                        var td = et.Resolve ();
                                        IMetadataScope scope = et.Scope;
                                        if ((td != null) && Annotations.IsMarked (td)) {
-                                               scope = assembly.MainModule.Import (td).Scope;
+                                               scope = assembly.MainModule.ImportReference (td).Scope;
                                                hash.Add (td, scope);
                                        }
                                }
index 23aca21a84908c5153725cbcb77ec3fe02bb14f3..cb0646c6871d50e77ef8dd30560e2b91101ce52c 100644 (file)
@@ -65,7 +65,7 @@ namespace Mono.Linker {
                public void CacheAssembly (AssemblyDefinition assembly)
                {
                        _assemblies [assembly.Name.Name] = assembly;
-                       base.AddSearchDirectory (Path.GetDirectoryName (assembly.MainModule.FullyQualifiedName));
+                       base.AddSearchDirectory (Path.GetDirectoryName (assembly.MainModule.FileName));
                }
        }
 }
index 417206ce0798843fb35d1584fbb132cd8e74e21b..7d7908f2ec37e944bad42ab297b54b2f997dbb79 100644 (file)
@@ -178,7 +178,7 @@ namespace Mono.Linker {
                                if (_symbolReaderProvider != null) {
                                        var symbolReader = _symbolReaderProvider.GetSymbolReader (
                                                assembly.MainModule,
-                                               assembly.MainModule.FullyQualifiedName);
+                                               assembly.MainModule.FileName);
 
                                        _annotations.AddSymbolReader (assembly, symbolReader);
                                        assembly.MainModule.ReadSymbols (symbolReader);
index b6244881f61d564bb9115a578ab81bd474486f95..702d74d16a7dd43ecab4b9be6f71f9017fe6f755 100755 (executable)
@@ -52,6 +52,7 @@ class MakeBundle {
        static bool custom_mode = true;
        static string embedded_options = null;
        static string runtime = null;
+       static Dictionary<string,string> environment = new Dictionary<string,string>();
        static string [] i18n = new string [] {
                "West",
                ""
@@ -281,6 +282,19 @@ class MakeBundle {
                        case "--quiet":
                                quiet = true;
                                break;
+                       case "-e":
+                       case "--env":
+                               if (i+1 == top) {
+                                       Help ();
+                                       return 1;
+                               }
+                               var env = args [++i];
+                               var p = env.IndexOf ('=');
+                               if (p == -1)
+                                       environment.Add (env, "");
+                               else
+                                       environment.Add (env.Substring (0, p), env.Substring (p+1));
+                               break;
                        default:
                                sources.Add (args [i]);
                                break;
@@ -477,6 +491,26 @@ class MakeBundle {
                        package.Position = package.Position + (align - (package.Position % align));
                }
 
+               public void AddStringPair (string entry, string key, string value)
+               {
+                       var kbytes = Encoding.UTF8.GetBytes (key);
+                       var vbytes = Encoding.UTF8.GetBytes (value);
+
+                       Console.WriteLine ("ADDING {0} to {1}", key, value);
+                       if (kbytes.Length > 255){
+                               Console.WriteLine ("The key value can not exceed 255 characters: " + key);
+                               Environment.Exit (1);
+                       }
+                               
+                       locations [entry] = Tuple.Create (package.Position, kbytes.Length+vbytes.Length+3);
+                       package.WriteByte ((byte)kbytes.Length);
+                       package.Write (kbytes, 0, kbytes.Length);
+                       package.WriteByte (0);
+                       package.Write (vbytes, 0, vbytes.Length);
+                       package.WriteByte (0);
+                       package.Position = package.Position + (align - (package.Position % align));
+               }
+
                public void Dump ()
                {
                        if (quiet)
@@ -564,6 +598,10 @@ class MakeBundle {
                        maker.Add ("config_dir:", config_dir);
                if (embedded_options != null)
                        maker.AddString ("options:", embedded_options);
+               if (environment.Count > 0){
+                       foreach (var key in environment.Keys)
+                               maker.AddStringPair ("env:" + key, key, environment [key]);
+               }
                maker.Dump ();
                maker.Close ();
                return true;
@@ -1080,6 +1118,7 @@ void          mono_register_config_for_assembly (const char* assembly_name, cons
                                   "    --options OPTIONS   Embed the specified Mono command line options on target\n" +
                                   "    --runtime RUNTIME   Manually specifies the Mono runtime to use\n" +
                                   "    --target-server URL Specified a server to download targets from, default is " + target_server + "\n" +
+                                  "    --env KEY=VALUE     Hardcodes an environment variable for the target\n" +
                                   "\n" +
                                   "--custom   Builds a custom launcher, options for --custom\n" +
                                   "    -c                  Produce stub only, do not compile\n" +
index e99f07415765bc21b618798f6d7c132a22d0a1e1..2acb5ca3f5ac98c5c743ea4235ce938a46b4ecb9 100644 (file)
@@ -342,10 +342,19 @@ namespace Xamarin.ApiDiff {
                                if (i > 0)
                                        change.Append (", ");
 
+                               string mods_tgt = tgt [i].GetAttribute ("direction") ?? "";
+                               string mods_src = src [i].GetAttribute ("direction") ?? "";
+
+                               if (mods_tgt.Length > 0)
+                                       mods_tgt = mods_tgt + " ";
+
+                               if (mods_src.Length > 0)
+                                       mods_src = mods_src + " ";
+
                                if (i >= srcCount) {
-                                       change.AppendAdded (tgt [i].GetTypeName ("type") + " " + tgt [i].GetAttribute ("name"), true);
+                                       change.AppendAdded (mods_tgt + tgt [i].GetTypeName ("type") + " " + tgt [i].GetAttribute ("name"), true);
                                } else if (i >= tgtCount) {
-                                       change.AppendRemoved (src [i].GetTypeName ("type") + " " + src [i].GetAttribute ("name"), true);
+                                       change.AppendRemoved (mods_src + src [i].GetTypeName ("type") + " " + src [i].GetAttribute ("name"), true);
                                } else {
                                        var paramSourceType = src [i].GetTypeName ("type");
                                        var paramTargetType = tgt [i].GetTypeName ("type");
@@ -353,6 +362,12 @@ namespace Xamarin.ApiDiff {
                                        var paramSourceName = src [i].GetAttribute ("name");
                                        var paramTargetName = tgt [i].GetAttribute ("name");
 
+                                       if (mods_src != mods_tgt) {
+                                               change.AppendModified (mods_src, mods_tgt, true);
+                                       } else {
+                                               change.Append (mods_src);
+                                       }
+
                                        if (paramSourceType != paramTargetType) {
                                                change.AppendModified (paramSourceType, paramTargetType, true);
                                        } else {
@@ -360,7 +375,7 @@ namespace Xamarin.ApiDiff {
                                        }
                                        change.Append (" ");
                                        if (paramSourceName != paramTargetName) {
-                                               change.AppendModified (paramSourceName, paramTargetName, false);
+                                               change.AppendModified (paramSourceName, paramTargetName, true);
                                        } else {
                                                change.Append (paramSourceName);
                                        }
index 734aa3a166015a405e1b8bcaa34ccf285689642f..a204788306bb274ca648c24aca209d39d34fac60 100644 (file)
@@ -57,7 +57,7 @@ namespace Mono
                                return null;
                        }
 
-                       assemblyPath = (exeFiles.Length > 0)? exeFiles[0] : dllFiles[0];
+                       assemblyPath = exeFiles.Length > 0 ? exeFiles[0] : dllFiles[0];
 
                        var locProvider = new AssemblyLocationProvider (assemblyPath, logger);
 
@@ -97,10 +97,13 @@ namespace Mono
                                var dllFiles = Directory.GetFiles (dir, "*.dll");
                                var assemblies = exeFiles.Concat (dllFiles);
                                foreach (var assemblyPath in assemblies) {
-                                       var mdbPath = assemblyPath + ".mdb";
-                                       if (!File.Exists (mdbPath)) {
-                                               logger.LogWarning ("Directory {0} contains {1} but no mdb {2}.", dir, Path.GetFileName (assemblyPath), Path.GetFileName (mdbPath));
-                                               // assemblies without mdb files are useless
+
+                                       // TODO: Ignore embedded pdb
+                                       var symbolFile = GetSymbolFile (assemblyPath);
+
+                                       if (symbolFile == null) {
+                                               logger.LogWarning ("Directory {0} contains {1} but no debug symbols file was found.", dir, Path.GetFileName (assemblyPath));
+                                               // assemblies without debug symbols are useless
                                                continue;
                                        }
 
@@ -112,7 +115,7 @@ namespace Mono
                                        if (Directory.Exists (mvidDir)) {
                                                try {
                                                        Directory.Delete (mvidDir, true);
-                                               } catch (DirectoryNotFoundException e) {}
+                                               } catch (DirectoryNotFoundException) {}
                                        }
 
                                        Directory.CreateDirectory (mvidDir);
@@ -120,12 +123,26 @@ namespace Mono
                                        var mvidAssemblyPath = Path.Combine (mvidDir, Path.GetFileName (assemblyPath));
                                        File.Copy (assemblyPath, mvidAssemblyPath);
 
-                                       var mvidMdbPath = Path.Combine (mvidDir, Path.GetFileName (mdbPath));
-                                       File.Copy (mdbPath, mvidMdbPath);
+                                       var mvidDebugPath = Path.Combine (mvidDir, Path.GetFileName (symbolFile));
+                                       File.Copy (symbolFile, mvidDebugPath);
 
                                        // TODO create MVID dir for non main modules with links to main module MVID
                                }
                        }
                }
+
+               static string GetSymbolFile (string assembly)
+               {
+                       var pdbName = Path.ChangeExtension (assembly, "pdb");
+                       if (File.Exists (pdbName))
+                               return pdbName;
+                       
+                       var mdbName = assembly + ".mdb";
+
+                       if (File.Exists (mdbName))
+                               return mdbName;
+
+                       return null;
+               }
        }
 }
index dcf29b0f693c1b319df59b4d8b0549003bae1251..d242cb0b9cafe27bf9a9bf00a0f986b20b22453a 100644 (file)
@@ -47,7 +47,6 @@
     <Compile Include="symbolicate.cs" />\r
     <Compile Include="Logger.cs" />\r
     <Compile Include="StackFrameData.cs" />\r
-    <Compile Include="StackTraceMetadata.cs" />\r
     <Compile Include="SymbolManager.cs" />\r
     <Compile Include="..\..\class\Mono.Options\Mono.Options\Options.cs">\r
       <Link>Options.cs</Link>\r
index 8d6389b615b47aaeb7179ea646daccc14b15978e..69958598dda2c3386fb92a7adaadf4bc26f31da7 100644 (file)
@@ -477,12 +477,12 @@ namespace Mono.Tuner {
                        while (type != null) {
                                // does the type implements it itself
                                if (type.HasInterfaces) {
-                                       foreach (TypeReference iface in type.Interfaces) {
-                                               string fullname = (generic) ? iface.GetElementType ().FullName : iface.FullName;
+                                       foreach (var iface in type.Interfaces) {
+                                               string fullname = (generic) ? iface.InterfaceType.GetElementType ().FullName : iface.InterfaceType.FullName;
                                                if (fullname == interfaceName)
                                                        return true;
                                                //if not, then maybe one of its parent interfaces does
-                                               if (Implements (iface.Resolve (), interfaceName, generic))
+                                               if (Implements (iface.InterfaceType.Resolve (), interfaceName, generic))
                                                        return true;
                                        }
                                }
index ffe1f63b83831bf76308f05d066a6bcd62b5828e..b28194f9a2f441490d755fa04051c20e84eac87b 100644 (file)
                <FileWrites Include="$(TargetFrameworkMonikerAssemblyAttributesPath)" />
        </ItemGroup>
 
-       <Target Name="GenerateTargetFrameworkMonikerAttribute"
+       <Target Name="_GenerateTargetFrameworkMonikerAttribute"
                DependsOnTargets="PrepareForBuild;GetReferenceAssemblyPaths"
                Inputs="$(MSBuildToolsPath)\Microsoft.Common.targets"
-               Outputs="$(TargetFrameworkMonikerAssemblyAttributesPath)"
-               Condition="'$(GenerateTargetFrameworkAttribute)' == 'true'">
+               Outputs="$(TargetFrameworkMonikerAssemblyAttributesPath)">
 
                <WriteLinesToFile
                        File="$(TargetFrameworkMonikerAssemblyAttributesPath)"
                        ContinueOnError="true"
                        Condition="'@(Compile)' != '' and '$(TargetFrameworkMonikerAssemblyAttributeText)' != ''"
                />
+       </Target>
+
+       <Target Name="GenerateTargetFrameworkMonikerAttribute"
+               DependsOnTargets="_GenerateTargetFrameworkMonikerAttribute"
+               Condition="'$(GenerateTargetFrameworkAttribute)' == 'true'">
 
                <ItemGroup Condition="'@(Compile)' != '' and '$(TargetFrameworkMonikerAssemblyAttributeText)' != ''">
                        <Compile Include="$(TargetFrameworkMonikerAssemblyAttributesPath)"/>
index 433cffe8e69a8bfb86808755e4bfa26911c7d77a..89afe6502c780f8661c658ba53f8843818a90537 100644 (file)
                <FileWrites Include="$(TargetFrameworkMonikerAssemblyAttributesPath)" />
        </ItemGroup>
 
-       <Target Name="GenerateTargetFrameworkMonikerAttribute"
+       <Target Name="_GenerateTargetFrameworkMonikerAttribute"
                DependsOnTargets="PrepareForBuild;GetReferenceAssemblyPaths"
                Inputs="$(MSBuildToolsPath)\Microsoft.Common.targets"
-               Outputs="$(TargetFrameworkMonikerAssemblyAttributesPath)"
-               Condition="'$(GenerateTargetFrameworkAttribute)' == 'true'">
+               Outputs="$(TargetFrameworkMonikerAssemblyAttributesPath)">
 
                <WriteLinesToFile
                        File="$(TargetFrameworkMonikerAssemblyAttributesPath)"
                        ContinueOnError="true"
                        Condition="'@(Compile)' != '' and '$(TargetFrameworkMonikerAssemblyAttributeText)' != ''"
                />
+       </Target>
+
+       <Target Name="GenerateTargetFrameworkMonikerAttribute"
+               DependsOnTargets="_GenerateTargetFrameworkMonikerAttribute"
+               Condition="'$(GenerateTargetFrameworkAttribute)' == 'true'">
 
                <ItemGroup Condition="'@(Compile)' != '' and '$(TargetFrameworkMonikerAssemblyAttributeText)' != ''">
                        <Compile Include="$(TargetFrameworkMonikerAssemblyAttributesPath)"/>
index 152dd2b985e906f5ed3e6ac13142dd6e90198390..ff82f8195fe89bb67b6a224cb89bea9ae8bd9112 100644 (file)
                <FileWrites Include="$(TargetFrameworkMonikerAssemblyAttributesPath)" />
        </ItemGroup>
 
-       <Target Name="GenerateTargetFrameworkMonikerAttribute"
+       <Target Name="_GenerateTargetFrameworkMonikerAttribute"
                DependsOnTargets="PrepareForBuild;GetReferenceAssemblyPaths"
                Inputs="$(MSBuildToolsPath)\Microsoft.Common.targets"
-               Outputs="$(TargetFrameworkMonikerAssemblyAttributesPath)"
-               Condition="'$(GenerateTargetFrameworkAttribute)' == 'true'">
+               Outputs="$(TargetFrameworkMonikerAssemblyAttributesPath)">
 
                <WriteLinesToFile
                        File="$(TargetFrameworkMonikerAssemblyAttributesPath)"
                        ContinueOnError="true"
                        Condition="'@(Compile)' != '' and '$(TargetFrameworkMonikerAssemblyAttributeText)' != ''"
                />
+       </Target>
+
+       <Target Name="GenerateTargetFrameworkMonikerAttribute"
+               DependsOnTargets="_GenerateTargetFrameworkMonikerAttribute"
+               Condition="'$(GenerateTargetFrameworkAttribute)' == 'true'">
 
                <ItemGroup Condition="'@(Compile)' != '' and '$(TargetFrameworkMonikerAssemblyAttributeText)' != ''">
                        <Compile Include="$(TargetFrameworkMonikerAssemblyAttributesPath)"/>
index 3a275dc83513af2c1aedabb890fa8a763fc29d61..496efa70bf2c349b406ddb0a722b5e6f5f57a18a 100644 (file)
@@ -1994,9 +1994,14 @@ gboolean MoveFile (const gunichar2 *name, const gunichar2 *dest_name)
                case EXDEV:
                        /* Ignore here, it is dealt with below */
                        break;
-                       
+
+               case ENOENT:
+                       /* We already know src exists. Must be dest that doesn't exist. */
+                       _wapi_set_last_path_error_from_errno (NULL, utf8_dest_name);
+                       break;
+
                default:
-                       _wapi_set_last_path_error_from_errno (NULL, utf8_name);
+                       _wapi_set_last_error_from_errno ();
                }
        }
        
index 3193bc58731a248858f96506a52c25fd1d34b09d..c4da3eceee1b54378d22bcca0c7675f6624cb081 100644 (file)
@@ -130,7 +130,6 @@ struct _WapiShellExecuteInfo
        
 #define DEBUG_PROCESS 0x00000001
 #define DEBUG_ONLY_THIS_PROCESS 0x00000002
-#define CREATE_SUSPENDED 0x00000004
 #define DETACHED_PROCESS 0x00000008
 #define CREATE_NEW_CONSOLE 0x00000010
 #define NORMAL_PRIORITY_CLASS 0x00000020
index ddf8e11464ee31340eef33d1c840a7b97c6bb482..448232dff9ca550e7c0f81a70e5b9b23dc2b1d55 100644 (file)
 
 #include <mono/io-layer/wapi.h>
 #include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/io-trace.h>
-#include <mono/utils/mono-logger-internals.h>
-#include <mono/utils/mono-time.h>
 #include <mono/utils/w32handle.h>
-#include <mono/utils/mono-threads.h>
-
-static gboolean own_if_signalled(gpointer handle)
-{
-       gboolean ret = FALSE;
-
-       if (mono_w32handle_issignalled (handle)) {
-               mono_w32handle_ops_own (handle);
-               ret = TRUE;
-       }
-
-       return(ret);
-}
-
-static gboolean own_if_owned(gpointer handle)
-{
-       gboolean ret = FALSE;
-
-       if (mono_w32handle_ops_isowned (handle)) {
-               mono_w32handle_ops_own (handle);
-               ret = TRUE;
-       }
-
-       return(ret);
-}
 
 /**
  * WaitForSingleObjectEx:
@@ -63,135 +35,21 @@ static gboolean own_if_owned(gpointer handle)
  * @handle's state is still not signalled.  %WAIT_FAILED - an error
  * occurred. %WAIT_IO_COMPLETION - the wait was ended by an APC.
  */
-guint32 WaitForSingleObjectEx(gpointer handle, guint32 timeout,
-                             gboolean alertable)
-{
-       guint32 ret, waited;
-       int thr_ret;
-       gboolean apc_pending = FALSE;
-       gint64 wait_start, timeout_in_ticks;
-
-       if ((GPOINTER_TO_UINT (handle) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) {
-               SetLastError (ERROR_INVALID_HANDLE);
-               return(WAIT_FAILED);
-       }
-       
-       if (mono_w32handle_test_capabilities (handle,
-                                           MONO_W32HANDLE_CAP_WAIT) == FALSE) {
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p can't be waited for", __func__,
-                          handle);
-
-               return(WAIT_FAILED);
-       }
-
-       mono_w32handle_ops_prewait (handle);
-       
-       if (mono_w32handle_test_capabilities (handle, MONO_W32HANDLE_CAP_SPECIAL_WAIT) == TRUE) {
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p has special wait", __func__, handle);
-
-               ret = mono_w32handle_ops_specialwait (handle, timeout, alertable ? &apc_pending : NULL);
-       
-               if (apc_pending)
-                       ret = WAIT_IO_COMPLETION;
-
-               return ret;
-       }
-       
-       
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: locking handle %p", __func__, handle);
-
-       thr_ret = mono_w32handle_lock_handle (handle);
-       g_assert (thr_ret == 0);
-
-       if (mono_w32handle_test_capabilities (handle,
-                                           MONO_W32HANDLE_CAP_OWN) == TRUE) {
-               if (own_if_owned (handle) == TRUE) {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p already owned", __func__,
-                                  handle);
-                       ret = WAIT_OBJECT_0;
-                       goto done;
-               }
-       }
-
-       if (own_if_signalled (handle) == TRUE) {
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p already signalled", __func__,
-                          handle);
-
-               ret=WAIT_OBJECT_0;
-               goto done;
-       }
-
-       if (timeout == 0) {
-               ret = WAIT_TIMEOUT;
-               goto done;
-       }
-       
-       if (timeout != INFINITE) {
-               wait_start = mono_100ns_ticks ();
-               timeout_in_ticks = (gint64)timeout * 10 * 1000; //can't overflow as timeout is 32bits
-       }
-
-       do {
-               /* Check before waiting on the condition, just in case
-                */
-               mono_w32handle_ops_prewait (handle);
-
-               if (own_if_signalled (handle)) {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p signalled", __func__,
-                                  handle);
-
-                       ret = WAIT_OBJECT_0;
-                       goto done;
-               }
-
-               if (timeout == INFINITE) {
-                       waited = mono_w32handle_timedwait_signal_handle (handle, INFINITE, FALSE, alertable ? &apc_pending : NULL);
-               } else {
-                       gint64 elapsed = mono_100ns_ticks () - wait_start;
-                       if (elapsed >= timeout_in_ticks) {
-                               ret = WAIT_TIMEOUT;
-                               goto done;
-                       }
-
-                       waited = mono_w32handle_timedwait_signal_handle (handle, (timeout_in_ticks - elapsed) / 10 / 1000, FALSE, alertable ? &apc_pending : NULL);
-               }
-
-               if(waited==0 && !apc_pending) {
-                       /* Condition was signalled, so hopefully
-                        * handle is signalled now.  (It might not be
-                        * if someone else got in before us.)
-                        */
-                       if (own_if_signalled (handle)) {
-                               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p signalled", __func__,
-                                          handle);
-
-                               ret=WAIT_OBJECT_0;
-                               goto done;
-                       }
-               
-                       /* Better luck next time */
-               }
-       } while(waited == 0 && !apc_pending);
-
-       /* Timeout or other error */
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: wait on handle %p error: %s", __func__, handle,
-                  strerror (waited));
-
-       ret = apc_pending ? WAIT_IO_COMPLETION : WAIT_TIMEOUT;
-
-done:
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unlocking handle %p", __func__, handle);
-       
-       thr_ret = mono_w32handle_unlock_handle (handle);
-       g_assert (thr_ret == 0);
-
-       return(ret);
-}
-
-guint32 WaitForSingleObject(gpointer handle, guint32 timeout)
+guint32 WaitForSingleObjectEx(gpointer handle, guint32 timeout, gboolean alertable)
 {
-       return WaitForSingleObjectEx (handle, timeout, FALSE);
+       MonoW32HandleWaitRet ret;
+
+       ret = mono_w32handle_wait_one (handle, timeout, alertable);
+       if (ret == MONO_W32HANDLE_WAIT_RET_SUCCESS_0)
+               return WAIT_OBJECT_0;
+       else if (ret == MONO_W32HANDLE_WAIT_RET_ALERTED)
+               return WAIT_IO_COMPLETION;
+       else if (ret == MONO_W32HANDLE_WAIT_RET_TIMEOUT)
+               return WAIT_TIMEOUT;
+       else if (ret == MONO_W32HANDLE_WAIT_RET_FAILED)
+               return WAIT_FAILED;
+       else
+               g_error ("%s: unknown ret value %d", __func__, ret);
 }
 
 
@@ -233,149 +91,19 @@ guint32 WaitForSingleObject(gpointer handle, guint32 timeout)
 guint32 SignalObjectAndWait(gpointer signal_handle, gpointer wait,
                            guint32 timeout, gboolean alertable)
 {
-       guint32 ret = 0, waited;
-       int thr_ret;
-       gboolean apc_pending = FALSE;
-       gint64 wait_start, timeout_in_ticks;
-
-       if ((GPOINTER_TO_UINT (signal_handle) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) {
-               SetLastError (ERROR_INVALID_HANDLE);
-               return(WAIT_FAILED);
-       }
-
-       if ((GPOINTER_TO_UINT (wait) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) {
-               SetLastError (ERROR_INVALID_HANDLE);
-               return(WAIT_FAILED);
-       }
-       
-       if (mono_w32handle_test_capabilities (signal_handle,
-                                           MONO_W32HANDLE_CAP_SIGNAL)==FALSE) {
-               return(WAIT_FAILED);
-       }
-       
-       if (mono_w32handle_test_capabilities (wait,
-                                           MONO_W32HANDLE_CAP_WAIT)==FALSE) {
-               return(WAIT_FAILED);
-       }
-
-       mono_w32handle_ops_prewait (wait);
-       
-       if (mono_w32handle_test_capabilities (wait, MONO_W32HANDLE_CAP_SPECIAL_WAIT) == TRUE) {
-               g_warning ("%s: handle %p has special wait, implement me!!",
-                          __func__, wait);
-
-               return (WAIT_FAILED);
-       }
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: locking handle %p", __func__, wait);
-
-       thr_ret = mono_w32handle_lock_handle (wait);
-       g_assert (thr_ret == 0);
-
-       mono_w32handle_ops_signal (signal_handle);
-
-       if (mono_w32handle_test_capabilities (wait, MONO_W32HANDLE_CAP_OWN)==TRUE) {
-               if (own_if_owned (wait)) {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p already owned", __func__,
-                                  wait);
-                       ret = WAIT_OBJECT_0;
-                       goto done;
-               }
-       }
-
-       if (own_if_signalled (wait)) {
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p already signalled", __func__, wait);
-
-               ret = WAIT_OBJECT_0;
-               goto done;
-       }
-
-       if (timeout != INFINITE) {
-               wait_start = mono_100ns_ticks ();
-               timeout_in_ticks = (gint64)timeout * 10 * 1000; //can't overflow as timeout is 32bits
-       }
-       do {
-               /* Check before waiting on the condition, just in case
-                */
-               mono_w32handle_ops_prewait (wait);
-       
-               if (own_if_signalled (wait)) {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p signalled", __func__, wait);
-
-                       ret = WAIT_OBJECT_0;
-                       goto done;
-               }
-
-               if (timeout == INFINITE) {
-                       waited = mono_w32handle_timedwait_signal_handle (wait, INFINITE, FALSE, alertable ? &apc_pending : NULL);
-               } else {
-                       gint64 elapsed = mono_100ns_ticks () - wait_start;
-                       if (elapsed >= timeout_in_ticks) {
-                               ret = WAIT_TIMEOUT;
-                               goto done;
-                       }
-
-                       waited = mono_w32handle_timedwait_signal_handle (wait, (timeout_in_ticks - elapsed) / 10 / 1000, FALSE, alertable ? &apc_pending : NULL);
-               }
-
-               if (waited==0 && !apc_pending) {
-                       /* Condition was signalled, so hopefully
-                        * handle is signalled now.  (It might not be
-                        * if someone else got in before us.)
-                        */
-                       if (own_if_signalled (wait)) {
-                               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p signalled", __func__,
-                                          wait);
-
-                               ret = WAIT_OBJECT_0;
-                               goto done;
-                       }
-               
-                       /* Better luck next time */
-               }
-       } while(waited == 0 && !apc_pending);
-
-       /* Timeout or other error */
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: wait on handle %p error: %s", __func__, wait, strerror (ret));
-
-       ret = apc_pending ? WAIT_IO_COMPLETION : WAIT_TIMEOUT;
-
-done:
-
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unlocking handle %p", __func__, wait);
-
-       thr_ret = mono_w32handle_unlock_handle (wait);
-       g_assert (thr_ret == 0);
-
-       return(ret);
-}
-
-static gboolean test_and_own (guint32 numobjects, gpointer *handles,
-                             gboolean waitall, guint32 *count,
-                             guint32 *lowest)
-{
-       gboolean done;
-       int i;
-       
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: locking handles", __func__);
-       
-       done = mono_w32handle_count_signalled_handles (numobjects, handles,
-                                                    waitall, count, lowest);
-       if (done == TRUE) {
-               if (waitall == TRUE) {
-                       for (i = 0; i < numobjects; i++) {
-                               own_if_signalled (handles[i]);
-                       }
-               } else {
-                       own_if_signalled (handles[*lowest]);
-               }
-       }
-       
-       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unlocking handles", __func__);
-
-       mono_w32handle_unlock_handles (numobjects, handles);
-
-       return(done);
+       MonoW32HandleWaitRet ret;
+
+       ret = mono_w32handle_signal_and_wait (signal_handle, wait, timeout, alertable);
+       if (ret == MONO_W32HANDLE_WAIT_RET_SUCCESS_0)
+               return WAIT_OBJECT_0;
+       else if (ret == MONO_W32HANDLE_WAIT_RET_ALERTED)
+               return WAIT_IO_COMPLETION;
+       else if (ret == MONO_W32HANDLE_WAIT_RET_TIMEOUT)
+               return WAIT_TIMEOUT;
+       else if (ret == MONO_W32HANDLE_WAIT_RET_FAILED)
+               return WAIT_FAILED;
+       else
+               g_error ("%s: unknown ret value %d", __func__, ret);
 }
 
 /**
@@ -412,208 +140,18 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
                                 gboolean waitall, guint32 timeout,
                                 gboolean alertable)
 {
-       gboolean duplicate = FALSE, bogustype = FALSE, done;
-       guint32 count, lowest;
-       guint i;
-       guint32 ret;
-       int thr_ret;
-       guint32 retval;
-       gboolean poll;
-       gpointer sorted_handles [MAXIMUM_WAIT_OBJECTS];
-       gboolean apc_pending = FALSE;
-       gint64 wait_start, timeout_in_ticks;
-       
-       if (numobjects > MAXIMUM_WAIT_OBJECTS) {
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Too many handles: %d", __func__, numobjects);
-
-               return(WAIT_FAILED);
-       }
-       
-       if (numobjects == 1) {
-               return WaitForSingleObjectEx (handles [0], timeout, alertable);
-       }
-
-       /* Check for duplicates */
-       for (i = 0; i < numobjects; i++) {
-               if ((GPOINTER_TO_UINT (handles[i]) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Handle %d pseudo process", __func__,
-                                  i);
-
-                       bogustype = TRUE;
-                       break;
-               }
-
-               if (mono_w32handle_test_capabilities (handles[i], MONO_W32HANDLE_CAP_WAIT) == FALSE) {
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Handle %p can't be waited for",
-                                  __func__, handles[i]);
-
-                       bogustype = TRUE;
-                       break;
-               }
-
-               sorted_handles [i] = handles [i];
-               mono_w32handle_ops_prewait (handles[i]);
-       }
-
-       qsort (sorted_handles, numobjects, sizeof (gpointer), g_direct_equal);
-       for (i = 1; i < numobjects; i++) {
-               if (sorted_handles [i - 1] == sorted_handles [i]) {
-                       duplicate = TRUE;
-                       break;
-               }
-       }
-
-       if (duplicate == TRUE) {
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Returning due to duplicates", __func__);
-
-               return(WAIT_FAILED);
-       }
-
-       if (bogustype == TRUE) {
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Returning due to bogus type", __func__);
-
-               return(WAIT_FAILED);
-       }
-
-       poll = FALSE;
-       for (i = 0; i < numobjects; ++i)
-               if (mono_w32handle_get_type (handles [i]) == MONO_W32HANDLE_PROCESS)
-                       /* Can't wait for a process handle + another handle without polling */
-                       poll = TRUE;
-
-       done = test_and_own (numobjects, handles, waitall, &count, &lowest);
-       if (done == TRUE) {
-               return(WAIT_OBJECT_0+lowest);
-       }
-       
-       if (timeout == 0) {
+       MonoW32HandleWaitRet ret;
+
+       ret = mono_w32handle_wait_multiple (handles, numobjects, waitall, timeout, alertable);
+       if (ret >= MONO_W32HANDLE_WAIT_RET_SUCCESS_0)
+               return WAIT_OBJECT_0 + (ret - MONO_W32HANDLE_WAIT_RET_SUCCESS_0);
+       else if (ret == MONO_W32HANDLE_WAIT_RET_ALERTED)
+               return WAIT_IO_COMPLETION;
+       else if (ret == MONO_W32HANDLE_WAIT_RET_TIMEOUT)
                return WAIT_TIMEOUT;
-       }
-
-       if (timeout != INFINITE) {
-               wait_start = mono_100ns_ticks ();
-               timeout_in_ticks = (gint64)timeout * 10 * 1000; //can't overflow as timeout is 32bits
-       }
-
-       /* Have to wait for some or all handles to become signalled
-        */
-
-       for (i = 0; i < numobjects; i++) {
-               /* Add a reference, as we need to ensure the handle wont
-                * disappear from under us while we're waiting in the loop
-                * (not lock, as we don't want exclusive access here)
-                */
-               mono_w32handle_ref (handles[i]);
-       }
-
-       while(1) {
-               /* Prod all handles with prewait methods and
-                * special-wait handles that aren't already signalled
-                */
-               for (i = 0; i < numobjects; i++) {
-                       mono_w32handle_ops_prewait (handles[i]);
-               
-                       if (mono_w32handle_test_capabilities (handles[i], MONO_W32HANDLE_CAP_SPECIAL_WAIT) == TRUE && mono_w32handle_issignalled (handles[i]) == FALSE) {
-                               mono_w32handle_ops_specialwait (handles[i], 0, alertable ? &apc_pending : NULL);
-                       }
-               }
-               
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: locking signal mutex", __func__);
-
-               thr_ret = mono_w32handle_lock_signal_mutex ();
-               g_assert (thr_ret == 0);
-
-               /* Check the signalled state of handles inside the critical section */
-               if (waitall) {
-                       done = TRUE;
-                       for (i = 0; i < numobjects; i++)
-                               if (!mono_w32handle_issignalled (handles [i]))
-                                       done = FALSE;
-               } else {
-                       done = FALSE;
-                       for (i = 0; i < numobjects; i++)
-                               if (mono_w32handle_issignalled (handles [i]))
-                                       done = TRUE;
-               }
-               
-               if (!done) {
-                       /* Enter the wait */
-                       if (timeout == INFINITE) {
-                               ret = mono_w32handle_timedwait_signal (INFINITE, poll, &apc_pending);
-                       } else {
-                               gint64 elapsed = mono_100ns_ticks () - wait_start;
-                               if (elapsed >= timeout_in_ticks) {
-                                       ret = WAIT_TIMEOUT;
-                               } else {
-                                       ret = mono_w32handle_timedwait_signal ((timeout_in_ticks - elapsed) / 10 / 1000, poll, &apc_pending);
-                               }
-                       }
-               } else {
-                       /* No need to wait */
-                       ret = 0;
-               }
-
-               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unlocking signal mutex", __func__);
-
-               thr_ret = mono_w32handle_unlock_signal_mutex ();
-               g_assert (thr_ret == 0);
-               
-               if (alertable && apc_pending) {
-                       retval = WAIT_IO_COMPLETION;
-                       break;
-               }
-       
-               /* Check if everything is signalled, as we can't
-                * guarantee to notice a shared signal even if the
-                * wait timed out
-                */
-               done = test_and_own (numobjects, handles, waitall,
-                                    &count, &lowest);
-               if (done == TRUE) {
-                       retval = WAIT_OBJECT_0+lowest;
-                       break;
-               } else if (ret != 0) {
-                       /* Didn't get all handles, and there was a timeout */
-                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: wait returned error: %s", __func__,
-                                  strerror (ret));
-
-                       retval = WAIT_TIMEOUT;
-                       break;
-               }
-       }
-
-       for (i = 0; i < numobjects; i++) {
-               /* Unref everything we reffed above */
-               mono_w32handle_unref (handles[i]);
-       }
-
-       return retval;
-}
-
-guint32 WaitForMultipleObjects(guint32 numobjects, gpointer *handles,
-                              gboolean waitall, guint32 timeout)
-{
-       return WaitForMultipleObjectsEx(numobjects, handles, waitall, timeout, FALSE);
-}
-
-/**
- * WaitForInputIdle:
- * @handle: a handle to the process to wait for
- * @timeout: the maximum time in milliseconds to wait for
- *
- * This function returns when either @handle process is waiting
- * for input, or @timeout ms elapses.  If @timeout is zero, the
- * process state is tested and the function returns immediately.
- * If @timeout is %INFINITE, the function waits forever.
- *
- * Return value: 0 - @handle process is waiting for input.
- * %WAIT_TIMEOUT - The @timeout interval elapsed and
- * @handle process is not waiting for input.  %WAIT_FAILED - an error
- * occurred. 
- */
-guint32 WaitForInputIdle(gpointer handle, guint32 timeout)
-{
-       /*TODO: Not implemented*/
-       return WAIT_TIMEOUT;
+       else if (ret == MONO_W32HANDLE_WAIT_RET_FAILED)
+               return WAIT_FAILED;
+       else
+               g_error ("%s: unknown ret value %d", __func__, ret);
 }
 
index a4ff149147efe3ee4cd17e8f01125002ad10083b..b1fef4b1479361fd065bc19bf43bae631003f823 100644 (file)
 #define _WAPI_WAIT_H_
 
 #include "mono/io-layer/status.h"
+#include "mono/utils/w32handle.h"
 
 G_BEGIN_DECLS
 
-#define MAXIMUM_WAIT_OBJECTS 64
-
 #define INFINITE               0xFFFFFFFF
 
 #define WAIT_FAILED            0xFFFFFFFF
@@ -27,16 +26,12 @@ G_BEGIN_DECLS
 #define WAIT_TIMEOUT           STATUS_TIMEOUT
 #define WAIT_IO_COMPLETION     STATUS_USER_APC
 
-extern guint32 WaitForSingleObject(gpointer handle, guint32 timeout);
 extern guint32 WaitForSingleObjectEx(gpointer handle, guint32 timeout, 
                                        gboolean alertable);
 extern guint32 SignalObjectAndWait(gpointer signal_handle, gpointer wait,
                                   guint32 timeout, gboolean alertable);
-extern guint32 WaitForMultipleObjects(guint32 numobjects, gpointer *handles,
-                                     gboolean waitall, guint32 timeout);
 extern guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
                                      gboolean waitall, guint32 timeout, gboolean alertable);
-extern guint32 WaitForInputIdle(gpointer handle, guint32 timeout);
 
 G_END_DECLS
 #endif /* _WAPI_WAIT_H_ */
index b848a483c7030aad42af1650541355d16f260836..8f8b4ff549d87ad0e142368bf773277c4e5351d7 100644 (file)
 #define GetFileVersionInfo wapi_GetFileVersionInfo 
 #define VerQueryValue wapi_VerQueryValue 
 #define VerLanguageName wapi_VerLanguageName 
-#define WaitForSingleObject wapi_WaitForSingleObject
 #define WaitForSingleObjectEx wapi_WaitForSingleObjectEx
 #define SignalObjectAndWait wapi_SignalObjectAndWait
-#define WaitForMultipleObjects wapi_WaitForMultipleObjects
 #define WaitForMultipleObjectsEx wapi_WaitForMultipleObjectsEx
-#define WaitForInputIdle wapi_WaitForInputIdle
 
 #endif /* __WAPI_REMAP_H__ */
index 32f5628d5f75c2bd602e7255bebff10d6e3c79bb..f49dde50193159d9d0525370300142fe2551b50c 100644 (file)
@@ -201,6 +201,12 @@ common_sources = \
        verify.c                \
        verify-internals.h      \
        wrapper-types.h \
+       dynamic-image-internals.h       \
+       dynamic-stream.c        \
+       dynamic-stream-internals.h      \
+       reflection-cache.h      \
+       custom-attrs-internals.h        \
+       sre-internals.h \
        reflection-internals.h  \
        file-mmap-posix.c       \
        file-mmap-windows.c     \
@@ -223,8 +229,14 @@ gc_dependent_sources = \
        monitor.c       \
        mono-hash.c     \
        object.c        \
+       dynamic-image.c \
+       sre.c   \
+       sre-encode.c    \
+       sre-save.c      \
+       custom-attrs.c  \
        reflection.c
 
+
 boehm_sources = \
        boehm-gc.c
 
index ae391b08948e86b49aa92aac222083d8e0214175..79c8406d46f11f8706ebe024dfd451fcc5918e6f 100644 (file)
@@ -83,7 +83,7 @@
  * Changes which are already detected at runtime, like the addition
  * of icalls, do not require an increment.
  */
-#define MONO_CORLIB_VERSION 152
+#define MONO_CORLIB_VERSION 154
 
 typedef struct
 {
@@ -1934,6 +1934,20 @@ mono_domain_assembly_search (MonoAssemblyName *aname,
        return NULL;
 }
 
+static gboolean
+prevent_running_reference_assembly (MonoAssembly *ass, MonoError *error)
+{
+       mono_error_init (error);
+       gboolean refasm = mono_assembly_get_reference_assembly_attribute (ass, error);
+       if (!is_ok (error))
+               return TRUE;
+       if (refasm) {
+               mono_error_set_bad_image (error, ass->image, "Could not load file or assembly or one of its dependencies. Reference assemblies should not be loaded for execution.  They can only be loaded in the Reflection-only loader context.\n");
+               return TRUE;
+       }
+       return FALSE;
+}
+
 MonoReflectionAssembly *
 ves_icall_System_Reflection_Assembly_LoadFrom (MonoString *fname, MonoBoolean refOnly)
 {
@@ -1942,37 +1956,40 @@ ves_icall_System_Reflection_Assembly_LoadFrom (MonoString *fname, MonoBoolean re
        MonoDomain *domain = mono_domain_get ();
        char *name, *filename;
        MonoImageOpenStatus status = MONO_IMAGE_OK;
-       MonoAssembly *ass;
+       MonoAssembly *ass = NULL;
+
+       name = NULL;
+       result = NULL;
+
+       mono_error_init (&error);
 
        if (fname == NULL) {
-               MonoException *exc = mono_get_exception_argument_null ("assemblyFile");
-               mono_set_pending_exception (exc);
-               return NULL;
+               mono_error_set_argument_null (&error, "assemblyFile", "");
+               goto leave;
        }
                
        name = filename = mono_string_to_utf8_checked (fname, &error);
-       if (mono_error_set_pending_exception (&error))
-               return NULL;
+       if (!is_ok (&error))
+               goto leave;
        
        ass = mono_assembly_open_full (filename, &status, refOnly);
        
        if (!ass) {
-               MonoException *exc;
-
                if (status == MONO_IMAGE_IMAGE_INVALID)
-                       exc = mono_get_exception_bad_image_format2 (NULL, fname);
+                       mono_error_set_bad_image_name (&error, name, "");
                else
-                       exc = mono_get_exception_file_not_found2 (NULL, fname);
-               g_free (name);
-               mono_set_pending_exception (exc);
-               return NULL;
+                       mono_error_set_exception_instance (&error, mono_get_exception_file_not_found2 (NULL, fname));
+               goto leave;
        }
 
-       g_free (name);
+       if (!refOnly && prevent_running_reference_assembly (ass, &error))
+               goto leave;
 
        result = mono_assembly_get_object_checked (domain, ass, &error);
-       if (!result)
-               mono_error_set_pending_exception (&error);
+
+leave:
+       mono_error_set_pending_exception (&error);
+       g_free (name);
        return result;
 }
 
@@ -2007,6 +2024,11 @@ ves_icall_System_AppDomain_LoadAssemblyRaw (MonoAppDomain *ad,
                return NULL; 
        }
 
+       if (!refonly && prevent_running_reference_assembly (ass, &error)) {
+               mono_error_set_pending_exception (&error);
+               return NULL;
+       }
+
        refass = mono_assembly_get_object_checked (domain, ass, &error);
        if (!refass)
                mono_error_set_pending_exception (&error);
@@ -2024,7 +2046,7 @@ ves_icall_System_AppDomain_LoadAssembly (MonoAppDomain *ad,  MonoString *assRef,
        MonoAssembly *ass;
        MonoAssemblyName aname;
        MonoReflectionAssembly *refass = NULL;
-       gchar *name;
+       gchar *name = NULL;
        gboolean parsed;
 
        g_assert (assRef);
@@ -2033,16 +2055,13 @@ ves_icall_System_AppDomain_LoadAssembly (MonoAppDomain *ad,  MonoString *assRef,
        if (mono_error_set_pending_exception (&error))
                return NULL;
        parsed = mono_assembly_name_parse (name, &aname);
-       g_free (name);
 
        if (!parsed) {
                /* This is a parse error... */
                if (!refOnly) {
                        refass = mono_try_assembly_resolve (domain, assRef, NULL, refOnly, &error);
-                       if (!mono_error_ok (&error)) {
-                               mono_error_set_pending_exception (&error);
-                               return NULL;
-                       }
+                       if (!is_ok (&error))
+                               goto leave;
                }
                return refass;
        }
@@ -2054,25 +2073,31 @@ ves_icall_System_AppDomain_LoadAssembly (MonoAppDomain *ad,  MonoString *assRef,
                /* MS.NET doesn't seem to call the assembly resolve handler for refonly assemblies */
                if (!refOnly) {
                        refass = mono_try_assembly_resolve (domain, assRef, NULL, refOnly, &error);
-                       if (!mono_error_ok (&error)) {
-                               mono_error_set_pending_exception (&error);
-                               return NULL;
-                       }
+                       if (!is_ok (&error))
+                               goto leave;
                }
                else
                        refass = NULL;
-               if (!refass) {
-                       return NULL;
-               }
+               if (!refass)
+                       goto leave;
+               ass = refass->assembly;
        }
 
-       if (refass == NULL)
+       if (!refOnly && prevent_running_reference_assembly (ass, &error))
+               goto leave;
+
+       g_assert (ass);
+       if (refass == NULL) {
                refass = mono_assembly_get_object_checked (domain, ass, &error);
+               if (!is_ok (&error))
+                       goto leave;
+       }
 
-       if (refass == NULL)
-               mono_error_set_pending_exception (&error);
-       else
-               MONO_OBJECT_SETREF (refass, evidence, evidence);
+       MONO_OBJECT_SETREF (refass, evidence, evidence);
+
+leave:
+       g_free (name);
+       mono_error_set_pending_exception (&error);
        return refass;
 }
 
@@ -2564,23 +2589,20 @@ mono_domain_try_unload (MonoDomain *domain, MonoObject **exc)
         */
        tp.priority = MONO_THREAD_PRIORITY_NORMAL;
        tp.stack_size = 0;
-       tp.creation_flags = CREATE_SUSPENDED;
+       tp.creation_flags = 0;
        thread_handle = mono_threads_create_thread (unload_thread_main, thread_data, &tp, &tid);
        if (thread_handle == NULL)
                return;
-       mono_thread_info_resume (tid);
 
        /* Wait for the thread */       
        while (!thread_data->done && guarded_wait (thread_handle, INFINITE, TRUE) == WAIT_IO_COMPLETION) {
                if (mono_thread_internal_has_appdomain_ref (mono_thread_internal_current (), domain) && (mono_thread_interruption_requested ())) {
                        /* The unload thread tries to abort us */
                        /* The icall wrapper will execute the abort */
-                       CloseHandle (thread_handle);
                        unload_data_unref (thread_data);
                        return;
                }
        }
-       CloseHandle (thread_handle);
 
        if (thread_data->failure_reason) {
                /* Roll back the state change */
index 4bad7dc5ed6d85719bd7426b3e906655c833c127..0744389c400bf4539c0d88f3e530df2a95436b6e 100644 (file)
@@ -203,6 +203,7 @@ 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);
@@ -1190,6 +1191,23 @@ mono_assembly_load_reference (MonoImage *image, int index)
                                   aname.major, aname.minor, aname.build, aname.revision,
                                   strlen ((char*)aname.public_key_token) == 0 ? "(none)" : (char*)aname.public_key_token, extra_msg);
                g_free (extra_msg);
+
+       } else if (!image->assembly->ref_only) {
+               MonoError error;
+               if (mono_assembly_get_reference_assembly_attribute (reference, &error)) {
+                       mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_ASSEMBLY, "The following reference assembly assembly referenced from %s was not loaded.  Reference assemblies should not be loaded for execution.  They can only be loaded in the Reflection-only loader context:\n"
+                                   "     Assembly:   %s    (assemblyref_index=%d)\n"
+                                   "     Version:    %d.%d.%d.%d\n"
+                                   "     Public Key: %s\n",
+                                   image->name, aname.name, index,
+                                   aname.major, aname.minor, aname.build, aname.revision,
+                                   strlen ((char*)aname.public_key_token) == 0 ? "(none)" : (char*)aname.public_key_token);
+                       reference = NULL; /* don't load reference assemblies for execution */
+               }
+               if (!is_ok (&error)) {
+                       reference = NULL;
+                       mono_error_cleanup (&error);
+               }
        }
 
        mono_assemblies_lock ();
@@ -1803,6 +1821,37 @@ mono_assembly_load_friends (MonoAssembly* ass)
        mono_assemblies_unlock ();
 }
 
+
+/**
+ * mono_assembly_get_reference_assembly_attribute:
+ * @assembly: a MonoAssembly
+ * @error: set on error.
+ *
+ * Returns TRUE if @assembly has the System.Runtime.CompilerServices.ReferenceAssemblyAttribute set.
+ * On error returns FALSE and sets @error.
+ */
+gboolean
+mono_assembly_get_reference_assembly_attribute (MonoAssembly *assembly, MonoError *error)
+{
+       mono_error_init (error);
+
+       MonoCustomAttrInfo *attrs = mono_custom_attrs_from_assembly_checked (assembly, error);
+       return_val_if_nok (error, FALSE);
+       if (!attrs)
+               return FALSE;
+       MonoClass *ref_asm_class = mono_class_try_get_reference_assembly_class ();
+       gboolean result = FALSE;
+       for (int i = 0; i < attrs->num_attrs; ++i) {
+               MonoCustomAttrEntry *attr = &attrs->attrs [i];
+               if (attr->ctor && attr->ctor->klass && attr->ctor->klass == ref_asm_class) {
+                       result = TRUE;
+                       break;
+               }
+       }
+       mono_custom_attrs_free (attrs);
+       return result;
+}
+
 /**
  * mono_assembly_open:
  * @filename: Opens the assembly pointed out by this name
index 41510b486e88139695f0f0109332effe0b59557f..d3153d29967deb995f5d80da007197e6f7575475 100644 (file)
@@ -22,6 +22,7 @@
 #include <mono/metadata/metadata-internals.h>
 #include <mono/metadata/marshal.h>
 #include <mono/metadata/runtime.h>
+#include <mono/metadata/handle.h>
 #include <mono/metadata/sgen-toggleref.h>
 #include <mono/utils/atomic.h>
 #include <mono/utils/mono-logger-internals.h>
@@ -388,6 +389,9 @@ boehm_thread_register (MonoThreadInfo* info, void *baseptr)
        res = GC_register_my_thread (&sb);
        if (res == GC_UNIMPLEMENTED)
            return NULL; /* Cannot happen with GC v7+. */
+
+       info->handle_stack = mono_handle_stack_alloc ();
+
        return info;
 }
 
@@ -424,7 +428,6 @@ on_gc_notification (GC_EventType event)
        switch (e) {
        case MONO_GC_EVENT_PRE_STOP_WORLD:
                MONO_GC_WORLD_STOP_BEGIN ();
-               mono_thread_info_suspend_lock ();
                break;
 
        case MONO_GC_EVENT_POST_STOP_WORLD:
@@ -437,7 +440,6 @@ on_gc_notification (GC_EventType event)
 
        case MONO_GC_EVENT_POST_START_WORLD:
                MONO_GC_WORLD_RESTART_END (1);
-               mono_thread_info_suspend_unlock ();
                break;
 
        case MONO_GC_EVENT_START:
@@ -477,7 +479,21 @@ on_gc_notification (GC_EventType event)
        }
 
        mono_profiler_gc_event (e, 0);
+
+       switch (e) {
+       case MONO_GC_EVENT_PRE_STOP_WORLD:
+               mono_thread_info_suspend_lock ();
+               mono_profiler_gc_event (MONO_GC_EVENT_PRE_STOP_WORLD_LOCKED, 0);
+               break;
+       case MONO_GC_EVENT_POST_START_WORLD:
+               mono_thread_info_suspend_unlock ();
+               mono_profiler_gc_event (MONO_GC_EVENT_POST_START_WORLD_UNLOCKED, 0);
+               break;
+       default:
+               break;
+       }
 }
+
  
 static void
 on_gc_heap_resize (size_t new_size)
@@ -769,7 +785,7 @@ mono_gc_invoke_finalizers (void)
        return 0;
 }
 
-gboolean
+MonoBoolean
 mono_gc_pending_finalizers (void)
 {
        return GC_should_invoke_finalizers ();
@@ -1912,5 +1928,9 @@ mono_gchandle_free_domain (MonoDomain *domain)
        }
 
 }
-
+#else
+       #ifdef _MSC_VER
+               // Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+               void __mono_win32_boehm_gc_quiet_lnk4221(void) {}
+       #endif
 #endif /* no Boehm GC */
index f51c979a50fab8ab5d230010e483867b188a7ed5..de54bd07a4d97ebde27235f64988583de477ac8b 100644 (file)
@@ -529,8 +529,9 @@ struct _MonoMethodInflated {
 struct _MonoGenericClass {
        MonoClass *container_class;     /* the generic type definition */
        MonoGenericContext context;     /* a context that contains the type instantiation doesn't contain any method instantiation */ /* FIXME: Only the class_inst member of "context" is ever used, so this field could be replaced with just a monogenericinst */
-       guint is_dynamic  : 1;          /* We're a MonoDynamicGenericClass */
+       guint is_dynamic  : 1;          /* Contains dynamic types */
        guint is_tb_open  : 1;          /* This is the fully open instantiation for a type_builder. Quite ugly, but it's temporary.*/
+       guint need_sync   : 1;      /* Only if dynamic. Need to be synchronized with its container class after its finished. */
        MonoClass *cached_class;        /* if present, the MonoClass corresponding to the instantiation.  */
 
        /* 
@@ -541,21 +542,6 @@ struct _MonoGenericClass {
        MonoImageSet *owner;
 };
 
-/*
- * This is used when instantiating a generic type definition which is
- * a TypeBuilder.
- */
-struct _MonoDynamicGenericClass {
-       MonoGenericClass generic_class;
-       int count_fields;
-       MonoClassField *fields;
-       guint initialized;
-       /* The non-inflated types of the fields */
-       MonoType **field_generic_types;
-       /* The managed objects representing the fields */
-       MonoObject **field_objects;
-};
-
 /*
  * A type parameter.
  */
index a419af381492313e250c7887c0217c26ea071269..7ec6ee9186e119598af72817dfe7df1bfd7e203f 100644 (file)
@@ -5591,6 +5591,7 @@ mono_class_setup_parent (MonoClass *klass, MonoClass *parent)
                        /* set the parent to something useful and safe, but mark the type as broken */
                        parent = mono_defaults.object_class;
                        mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+                       g_assert (parent);
                }
 
                klass->parent = parent;
diff --git a/mono/metadata/custom-attrs-internals.h b/mono/metadata/custom-attrs-internals.h
new file mode 100644 (file)
index 0000000..2f93fec
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef __MONO_METADATA_CUSTOM_ATTRS_INTERNALS_H__
+#define __MONO_METADATA_CUSTOM_ATTRS_INTERNALS_H__
+
+#include <mono/metadata/object.h>
+#include <mono/metadata/reflection.h>
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_builders (MonoImage *alloc_img, MonoImage *image, MonoArray *cattrs);
+
+#endif  /* __MONO_METADATA_REFLECTION_CUSTOM_ATTRS_INTERNALS_H__ */
diff --git a/mono/metadata/custom-attrs.c b/mono/metadata/custom-attrs.c
new file mode 100644 (file)
index 0000000..a1d48eb
--- /dev/null
@@ -0,0 +1,1720 @@
+/*
+ * custom-attrs.c: Custom attributes.
+ * 
+ * Author:
+ *   Paolo Molaro (lupus@ximian.com)
+ *
+ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
+ * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
+ * Copyright 2011 Rodrigo Kumpera
+ * Copyright 2016 Microsoft
+ *
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#include <config.h>
+#include "mono/metadata/gc-internals.h"
+#include "mono/metadata/mono-endian.h"
+#include "mono/metadata/object-internals.h"
+#include "mono/metadata/reflection-cache.h"
+#include "mono/metadata/custom-attrs-internals.h"
+#include "mono/metadata/sre-internals.h"
+#include "mono/metadata/reflection-internals.h"
+#include "mono/metadata/tabledefs.h"
+#include "mono/metadata/tokentype.h"
+#include "mono/metadata/verify-internals.h"
+#include "mono/utils/checked-build.h"
+
+
+#define CHECK_ADD4_OVERFLOW_UN(a, b) ((guint32)(0xFFFFFFFFU) - (guint32)(b) < (guint32)(a))
+#define CHECK_ADD8_OVERFLOW_UN(a, b) ((guint64)(0xFFFFFFFFFFFFFFFFUL) - (guint64)(b) < (guint64)(a))
+
+#if SIZEOF_VOID_P == 4
+#define CHECK_ADDP_OVERFLOW_UN(a,b) CHECK_ADD4_OVERFLOW_UN(a, b)
+#else
+#define CHECK_ADDP_OVERFLOW_UN(a,b) CHECK_ADD8_OVERFLOW_UN(a, b)
+#endif
+
+#define ADDP_IS_GREATER_OR_OVF(a, b, c) (((a) + (b) > (c)) || CHECK_ADDP_OVERFLOW_UN (a, b))
+#define ADD_IS_GREATER_OR_OVF(a, b, c) (((a) + (b) > (c)) || CHECK_ADD4_OVERFLOW_UN (a, b))
+
+static gboolean type_is_reference (MonoType *type);
+
+static GENERATE_GET_CLASS_WITH_CACHE (custom_attribute_typed_argument, System.Reflection, CustomAttributeTypedArgument);
+static GENERATE_GET_CLASS_WITH_CACHE (custom_attribute_named_argument, System.Reflection, CustomAttributeNamedArgument);
+
+/*
+ * LOCKING: Acquires the loader lock. 
+ */
+static MonoCustomAttrInfo*
+lookup_custom_attr (MonoImage *image, gpointer member)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       MonoCustomAttrInfo* res;
+
+       res = (MonoCustomAttrInfo *)mono_image_property_lookup (image, member, MONO_PROP_DYNAMIC_CATTR);
+
+       if (!res)
+               return NULL;
+
+       res = (MonoCustomAttrInfo *)g_memdup (res, MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * res->num_attrs);
+       res->cached = 0;
+       return res;
+}
+
+static gboolean
+custom_attr_visible (MonoImage *image, MonoReflectionCustomAttr *cattr)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       /* 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;
+
+               if ((visibility != TYPE_ATTRIBUTE_PUBLIC) && (visibility != TYPE_ATTRIBUTE_NESTED_PUBLIC))
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+
+static gboolean
+type_is_reference (MonoType *type)
+{
+       switch (type->type) {
+       case MONO_TYPE_BOOLEAN:
+       case MONO_TYPE_CHAR:
+       case MONO_TYPE_U:
+       case MONO_TYPE_I:
+       case MONO_TYPE_U1:
+       case MONO_TYPE_I1:
+       case MONO_TYPE_U2:
+       case MONO_TYPE_I2:
+       case MONO_TYPE_U4:
+       case MONO_TYPE_I4:
+       case MONO_TYPE_U8:
+       case MONO_TYPE_I8:
+       case MONO_TYPE_R8:
+       case MONO_TYPE_R4:
+       case MONO_TYPE_VALUETYPE:
+               return FALSE;
+       default:
+               return TRUE;
+       }
+}
+
+static void
+free_param_data (MonoMethodSignature *sig, void **params) {
+       int i;
+       for (i = 0; i < sig->param_count; ++i) {
+               if (!type_is_reference (sig->params [i]))
+                       g_free (params [i]);
+       }
+}
+
+/*
+ * Find the field index in the metadata FieldDef table.
+ */
+static guint32
+find_field_index (MonoClass *klass, MonoClassField *field) {
+       int i;
+
+       for (i = 0; i < klass->field.count; ++i) {
+               if (field == &klass->fields [i])
+                       return klass->field.first + 1 + i;
+       }
+       return 0;
+}
+
+/*
+ * Find the property index in the metadata Property table.
+ */
+static guint32
+find_property_index (MonoClass *klass, MonoProperty *property) {
+       int i;
+
+       for (i = 0; i < klass->ext->property.count; ++i) {
+               if (property == &klass->ext->properties [i])
+                       return klass->ext->property.first + 1 + i;
+       }
+       return 0;
+}
+
+/*
+ * Find the event index in the metadata Event table.
+ */
+static guint32
+find_event_index (MonoClass *klass, MonoEvent *event) {
+       int i;
+
+       for (i = 0; i < klass->ext->event.count; ++i) {
+               if (event == &klass->ext->events [i])
+                       return klass->ext->event.first + 1 + i;
+       }
+       return 0;
+}
+
+/*
+ * Load the type with name @n on behalf of image @image.  On failure sets @error and returns NULL.
+ * The @is_enum flag only affects the error message that's displayed on failure.
+ */
+static MonoType*
+cattr_type_from_name (char *n, MonoImage *image, gboolean is_enum, MonoError *error)
+{
+       MonoError inner_error;
+       MonoType *t = mono_reflection_type_from_name_checked (n, image, &inner_error);
+       if (!t) {
+               mono_error_set_type_load_name (error, g_strdup(n), NULL,
+                                              "Could not load %s %s while decoding custom attribute: %s",
+                                              is_enum ? "enum type": "type",
+                                              n,
+                                              mono_error_get_message (&inner_error));
+               mono_error_cleanup (&inner_error);
+               return NULL;
+       }
+       return t;
+}
+
+static MonoClass*
+load_cattr_enum_type (MonoImage *image, const char *p, const char **end, MonoError *error)
+{
+       char *n;
+       MonoType *t;
+       int slen = mono_metadata_decode_value (p, &p);
+
+       mono_error_init (error);
+
+       n = (char *)g_memdup (p, slen + 1);
+       n [slen] = 0;
+       t = cattr_type_from_name (n, image, TRUE, error);
+       g_free (n);
+       return_val_if_nok (error, NULL);
+       p += slen;
+       *end = p;
+       return mono_class_from_mono_type (t);
+}
+
+static void*
+load_cattr_value (MonoImage *image, MonoType *t, const char *p, const char **end, MonoError *error)
+{
+       int slen, type = t->type;
+       MonoClass *tklass = t->data.klass;
+
+       mono_error_init (error);
+
+handle_enum:
+       switch (type) {
+       case MONO_TYPE_U1:
+       case MONO_TYPE_I1:
+       case MONO_TYPE_BOOLEAN: {
+               MonoBoolean *bval = (MonoBoolean *)g_malloc (sizeof (MonoBoolean));
+               *bval = *p;
+               *end = p + 1;
+               return bval;
+       }
+       case MONO_TYPE_CHAR:
+       case MONO_TYPE_U2:
+       case MONO_TYPE_I2: {
+               guint16 *val = (guint16 *)g_malloc (sizeof (guint16));
+               *val = read16 (p);
+               *end = p + 2;
+               return val;
+       }
+#if SIZEOF_VOID_P == 4
+       case MONO_TYPE_U:
+       case MONO_TYPE_I:
+#endif
+       case MONO_TYPE_R4:
+       case MONO_TYPE_U4:
+       case MONO_TYPE_I4: {
+               guint32 *val = (guint32 *)g_malloc (sizeof (guint32));
+               *val = read32 (p);
+               *end = p + 4;
+               return val;
+       }
+#if SIZEOF_VOID_P == 8
+       case MONO_TYPE_U: /* error out instead? this should probably not happen */
+       case MONO_TYPE_I:
+#endif
+       case MONO_TYPE_U8:
+       case MONO_TYPE_I8: {
+               guint64 *val = (guint64 *)g_malloc (sizeof (guint64));
+               *val = read64 (p);
+               *end = p + 8;
+               return val;
+       }
+       case MONO_TYPE_R8: {
+               double *val = (double *)g_malloc (sizeof (double));
+               readr8 (p, val);
+               *end = p + 8;
+               return val;
+       }
+       case MONO_TYPE_VALUETYPE:
+               if (t->data.klass->enumtype) {
+                       type = mono_class_enum_basetype (t->data.klass)->type;
+                       goto handle_enum;
+               } else {
+                       MonoClass *k =  t->data.klass;
+                       
+                       if (mono_is_corlib_image (k->image) && strcmp (k->name_space, "System") == 0 && strcmp (k->name, "DateTime") == 0){
+                               guint64 *val = (guint64 *)g_malloc (sizeof (guint64));
+                               *val = read64 (p);
+                               *end = p + 8;
+                               return val;
+                       }
+               }
+               g_error ("generic valutype %s not handled in custom attr value decoding", t->data.klass->name);
+               break;
+               
+       case MONO_TYPE_STRING:
+               if (*p == (char)0xFF) {
+                       *end = p + 1;
+                       return NULL;
+               }
+               slen = mono_metadata_decode_value (p, &p);
+               *end = p + slen;
+               return mono_string_new_len_checked (mono_domain_get (), p, slen, error);
+       case MONO_TYPE_CLASS: {
+               MonoReflectionType *rt;
+               char *n;
+               MonoType *t;
+               if (*p == (char)0xFF) {
+                       *end = p + 1;
+                       return NULL;
+               }
+handle_type:
+               slen = mono_metadata_decode_value (p, &p);
+               n = (char *)g_memdup (p, slen + 1);
+               n [slen] = 0;
+               t = cattr_type_from_name (n, image, FALSE, error);
+               g_free (n);
+               return_val_if_nok (error, NULL);
+               *end = p + slen;
+
+               rt = mono_type_get_object_checked (mono_domain_get (), t, error);
+               if (!mono_error_ok (error))
+                       return NULL;
+
+               return rt;
+       }
+       case MONO_TYPE_OBJECT: {
+               char subt = *p++;
+               MonoObject *obj;
+               MonoClass *subc = NULL;
+               void *val;
+
+               if (subt == 0x50) {
+                       goto handle_type;
+               } else if (subt == 0x0E) {
+                       type = MONO_TYPE_STRING;
+                       goto handle_enum;
+               } else if (subt == 0x1D) {
+                       MonoType simple_type = {{0}};
+                       int etype = *p;
+                       p ++;
+
+                       type = MONO_TYPE_SZARRAY;
+                       if (etype == 0x50) {
+                               tklass = mono_defaults.systemtype_class;
+                       } else if (etype == 0x55) {
+                               tklass = load_cattr_enum_type (image, p, &p, error);
+                               if (!mono_error_ok (error))
+                                       return NULL;
+                       } else {
+                               if (etype == 0x51)
+                                       /* See Partition II, Appendix B3 */
+                                       etype = MONO_TYPE_OBJECT;
+                               simple_type.type = (MonoTypeEnum)etype;
+                               tklass = mono_class_from_mono_type (&simple_type);
+                       }
+                       goto handle_enum;
+               } else if (subt == 0x55) {
+                       char *n;
+                       MonoType *t;
+                       slen = mono_metadata_decode_value (p, &p);
+                       n = (char *)g_memdup (p, slen + 1);
+                       n [slen] = 0;
+                       t = cattr_type_from_name (n, image, FALSE, error);
+                       g_free (n);
+                       return_val_if_nok (error, NULL);
+                       p += slen;
+                       subc = mono_class_from_mono_type (t);
+               } else if (subt >= MONO_TYPE_BOOLEAN && subt <= MONO_TYPE_R8) {
+                       MonoType simple_type = {{0}};
+                       simple_type.type = (MonoTypeEnum)subt;
+                       subc = mono_class_from_mono_type (&simple_type);
+               } else {
+                       g_error ("Unknown type 0x%02x for object type encoding in custom attr", subt);
+               }
+               val = load_cattr_value (image, &subc->byval_arg, p, end, error);
+               obj = NULL;
+               if (mono_error_ok (error)) {
+                       obj = mono_object_new_checked (mono_domain_get (), subc, error);
+                       g_assert (!subc->has_references);
+                       if (mono_error_ok (error))
+                               mono_gc_memmove_atomic ((char*)obj + sizeof (MonoObject), val, mono_class_value_size (subc, NULL));
+               }
+
+               g_free (val);
+               return obj;
+       }
+       case MONO_TYPE_SZARRAY: {
+               MonoArray *arr;
+               guint32 i, alen, basetype;
+               alen = read32 (p);
+               p += 4;
+               if (alen == 0xffffffff) {
+                       *end = p;
+                       return NULL;
+               }
+               arr = mono_array_new_checked (mono_domain_get(), tklass, alen, error);
+               return_val_if_nok (error, NULL);
+               basetype = tklass->byval_arg.type;
+               if (basetype == MONO_TYPE_VALUETYPE && tklass->enumtype)
+                       basetype = mono_class_enum_basetype (tklass)->type;
+               switch (basetype)
+               {
+                       case MONO_TYPE_U1:
+                       case MONO_TYPE_I1:
+                       case MONO_TYPE_BOOLEAN:
+                               for (i = 0; i < alen; i++) {
+                                       MonoBoolean val = *p++;
+                                       mono_array_set (arr, MonoBoolean, i, val);
+                               }
+                               break;
+                       case MONO_TYPE_CHAR:
+                       case MONO_TYPE_U2:
+                       case MONO_TYPE_I2:
+                               for (i = 0; i < alen; i++) {
+                                       guint16 val = read16 (p);
+                                       mono_array_set (arr, guint16, i, val);
+                                       p += 2;
+                               }
+                               break;
+                       case MONO_TYPE_R4:
+                       case MONO_TYPE_U4:
+                       case MONO_TYPE_I4:
+                               for (i = 0; i < alen; i++) {
+                                       guint32 val = read32 (p);
+                                       mono_array_set (arr, guint32, i, val);
+                                       p += 4;
+                               }
+                               break;
+                       case MONO_TYPE_R8:
+                               for (i = 0; i < alen; i++) {
+                                       double val;
+                                       readr8 (p, &val);
+                                       mono_array_set (arr, double, i, val);
+                                       p += 8;
+                               }
+                               break;
+                       case MONO_TYPE_U8:
+                       case MONO_TYPE_I8:
+                               for (i = 0; i < alen; i++) {
+                                       guint64 val = read64 (p);
+                                       mono_array_set (arr, guint64, i, val);
+                                       p += 8;
+                               }
+                               break;
+                       case MONO_TYPE_CLASS:
+                       case MONO_TYPE_OBJECT:
+                       case MONO_TYPE_STRING:
+                       case MONO_TYPE_SZARRAY:
+                               for (i = 0; i < alen; i++) {
+                                       MonoObject *item = (MonoObject *)load_cattr_value (image, &tklass->byval_arg, p, &p, error);
+                                       if (!mono_error_ok (error))
+                                               return NULL;
+                                       mono_array_setref (arr, i, item);
+                               }
+                               break;
+                       default:
+                               g_error ("Type 0x%02x not handled in custom attr array decoding", basetype);
+               }
+               *end=p;
+               return arr;
+       }
+       default:
+               g_error ("Type 0x%02x not handled in custom attr value decoding", type);
+       }
+       return NULL;
+}
+
+static MonoObject*
+load_cattr_value_boxed (MonoDomain *domain, MonoImage *image, MonoType *t, const char* p, const char** end, MonoError *error)
+{
+       mono_error_init (error);
+
+       gboolean is_ref = type_is_reference (t);
+
+       void *val = load_cattr_value (image, t, p, end, error);
+       if (!is_ok (error)) {
+               if (is_ref)
+                       g_free (val);
+               return NULL;
+       }
+
+       if (is_ref)
+               return (MonoObject*)val;
+
+       MonoObject *boxed = mono_value_box_checked (domain, mono_class_from_mono_type (t), val, error);
+       g_free (val);
+       return boxed;
+}
+
+static MonoObject*
+create_cattr_typed_arg (MonoType *t, MonoObject *val, MonoError *error)
+{
+       static MonoMethod *ctor;
+       MonoObject *retval;
+       void *params [2], *unboxed;
+
+       mono_error_init (error);
+
+       if (!ctor)
+               ctor = mono_class_get_method_from_name (mono_class_get_custom_attribute_typed_argument_class (), ".ctor", 2);
+       
+       params [0] = mono_type_get_object_checked (mono_domain_get (), t, error);
+       return_val_if_nok (error, NULL);
+
+       params [1] = val;
+       retval = mono_object_new_checked (mono_domain_get (), mono_class_get_custom_attribute_typed_argument_class (), error);
+       return_val_if_nok (error, NULL);
+       unboxed = mono_object_unbox (retval);
+
+       mono_runtime_invoke_checked (ctor, unboxed, params, error);
+       return_val_if_nok (error, NULL);
+
+       return retval;
+}
+
+static MonoObject*
+create_cattr_named_arg (void *minfo, MonoObject *typedarg, MonoError *error)
+{
+       static MonoMethod *ctor;
+       MonoObject *retval;
+       void *unboxed, *params [2];
+
+       mono_error_init (error);
+
+       if (!ctor)
+               ctor = mono_class_get_method_from_name (mono_class_get_custom_attribute_named_argument_class (), ".ctor", 2);
+
+       params [0] = minfo;
+       params [1] = typedarg;
+       retval = mono_object_new_checked (mono_domain_get (), mono_class_get_custom_attribute_named_argument_class (), error);
+       return_val_if_nok (error, NULL);
+
+       unboxed = mono_object_unbox (retval);
+
+       mono_runtime_invoke_checked (ctor, unboxed, params, error);
+       return_val_if_nok (error, NULL);
+
+       return retval;
+}
+
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_builders (MonoImage *alloc_img, MonoImage *image, MonoArray *cattrs)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       int i, index, count, not_visible;
+       MonoCustomAttrInfo *ainfo;
+       MonoReflectionCustomAttr *cattr;
+
+       if (!cattrs)
+               return NULL;
+       /* FIXME: check in assembly the Run flag is set */
+
+       count = mono_array_length (cattrs);
+
+       /* Skip nonpublic attributes since MS.NET seems to do the same */
+       /* FIXME: This needs to be done more globally */
+       not_visible = 0;
+       for (i = 0; i < count; ++i) {
+               cattr = (MonoReflectionCustomAttr*)mono_array_get (cattrs, gpointer, i);
+               if (!custom_attr_visible (image, cattr))
+                       not_visible ++;
+       }
+
+       int num_attrs = count - not_visible;
+       ainfo = (MonoCustomAttrInfo *)mono_image_g_malloc0 (alloc_img, MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * num_attrs);
+
+       ainfo->image = image;
+       ainfo->num_attrs = num_attrs;
+       ainfo->cached = alloc_img != NULL;
+       index = 0;
+       for (i = 0; i < count; ++i) {
+               cattr = (MonoReflectionCustomAttr*)mono_array_get (cattrs, gpointer, i);
+               if (custom_attr_visible (image, cattr)) {
+                       unsigned char *saved = (unsigned char *)mono_image_alloc (image, mono_array_length (cattr->data));
+                       memcpy (saved, mono_array_addr (cattr->data, char, 0), mono_array_length (cattr->data));
+                       ainfo->attrs [index].ctor = cattr->ctor->method;
+                       g_assert (cattr->ctor->method);
+                       ainfo->attrs [index].data = saved;
+                       ainfo->attrs [index].data_size = mono_array_length (cattr->data);
+                       index ++;
+               }
+       }
+       g_assert (index == num_attrs && count == num_attrs + not_visible);
+
+       return ainfo;
+}
+
+
+static MonoObject*
+create_custom_attr (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len, MonoError *error)
+{
+       const char *p = (const char*)data;
+       const char *named;
+       guint32 i, j, num_named;
+       MonoObject *attr;
+       void *params_buf [32];
+       void **params = NULL;
+       MonoMethodSignature *sig;
+
+       mono_error_init (error);
+
+       mono_class_init (method->klass);
+
+       if (!mono_verifier_verify_cattr_content (image, method, data, len, NULL)) {
+               mono_error_set_generic_error (error, "System.Reflection", "CustomAttributeFormatException", "Binary format of the specified custom attribute was invalid.");
+               return NULL;
+       }
+
+       if (len == 0) {
+               attr = mono_object_new_checked (mono_domain_get (), method->klass, error);
+               if (!mono_error_ok (error)) return NULL;
+
+               mono_runtime_invoke_checked (method, attr, NULL, error);
+               if (!mono_error_ok (error))
+                       return NULL;
+
+               return attr;
+       }
+
+       if (len < 2 || read16 (p) != 0x0001) /* Prolog */
+               return NULL;
+
+       /*g_print ("got attr %s\n", method->klass->name);*/
+
+       sig = mono_method_signature (method);
+       if (sig->param_count < 32) {
+               params = params_buf;
+               memset (params, 0, sizeof (void*) * sig->param_count);
+       } else {
+               /* Allocate using GC so it gets GC tracking */
+               params = (void **)mono_gc_alloc_fixed (sig->param_count * sizeof (void*), MONO_GC_DESCRIPTOR_NULL, MONO_ROOT_SOURCE_REFLECTION, "custom attribute parameters");
+       }
+
+       /* skip prolog */
+       p += 2;
+       for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
+               params [i] = load_cattr_value (image, mono_method_signature (method)->params [i], p, &p, error);
+               if (!mono_error_ok (error))
+                       goto fail;
+       }
+
+       named = p;
+       attr = mono_object_new_checked (mono_domain_get (), method->klass, error);
+       if (!mono_error_ok (error)) goto fail;
+
+       MonoObject *exc = NULL;
+       mono_runtime_try_invoke (method, attr, params, &exc, error);
+       if (!mono_error_ok (error))
+               goto fail;
+       if (exc) {
+               mono_error_set_exception_instance (error, (MonoException*)exc);
+               goto fail;
+       }
+
+       num_named = read16 (named);
+       named += 2;
+       for (j = 0; j < num_named; j++) {
+               gint name_len;
+               char *name, named_type, data_type;
+               named_type = *named++;
+               data_type = *named++; /* type of data */
+               if (data_type == MONO_TYPE_SZARRAY)
+                       data_type = *named++;
+               if (data_type == MONO_TYPE_ENUM) {
+                       gint type_len;
+                       char *type_name;
+                       type_len = mono_metadata_decode_blob_size (named, &named);
+                       type_name = (char *)g_malloc (type_len + 1);
+                       memcpy (type_name, named, type_len);
+                       type_name [type_len] = 0;
+                       named += type_len;
+                       /* FIXME: lookup the type and check type consistency */
+                       g_free (type_name);
+               }
+               name_len = mono_metadata_decode_blob_size (named, &named);
+               name = (char *)g_malloc (name_len + 1);
+               memcpy (name, named, name_len);
+               name [name_len] = 0;
+               named += name_len;
+               if (named_type == 0x53) {
+                       MonoClassField *field;
+                       void *val;
+
+                       /* how this fail is a blackbox */
+                       field = mono_class_get_field_from_name (mono_object_class (attr), name);
+                       if (!field) {
+                               mono_error_set_generic_error (error, "System.Reflection", "CustomAttributeFormatException", "Could not find a field with name %s", name);
+                               g_free (name);
+                               goto fail;
+                       }
+
+                       val = load_cattr_value (image, field->type, named, &named, error);
+                       if (!mono_error_ok (error)) {
+                               g_free (name);
+                               if (!type_is_reference (field->type))
+                                       g_free (val);
+                               goto fail;
+                       }
+
+                       mono_field_set_value (attr, field, val);
+                       if (!type_is_reference (field->type))
+                               g_free (val);
+               } else if (named_type == 0x54) {
+                       MonoProperty *prop;
+                       void *pparams [1];
+                       MonoType *prop_type;
+
+                       prop = mono_class_get_property_from_name (mono_object_class (attr), name);
+
+                       if (!prop) {
+                               mono_error_set_generic_error (error, "System.Reflection", "CustomAttributeFormatException", "Could not find a property with name %s", name);
+                               g_free (name);
+                               goto fail;
+                       }
+
+                       if (!prop->set) {
+                               mono_error_set_generic_error (error, "System.Reflection", "CustomAttributeFormatException", "Could not find the setter for %s", name);
+                               g_free (name);
+                               goto fail;
+                       }
+
+                       /* can we have more that 1 arg in a custom attr named property? */
+                       prop_type = prop->get? mono_method_signature (prop->get)->ret :
+                            mono_method_signature (prop->set)->params [mono_method_signature (prop->set)->param_count - 1];
+
+                       pparams [0] = load_cattr_value (image, prop_type, named, &named, error);
+                       if (!mono_error_ok (error)) {
+                               g_free (name);
+                               if (!type_is_reference (prop_type))
+                                       g_free (pparams [0]);
+                               goto fail;
+                       }
+
+
+                       mono_property_set_value_checked (prop, attr, pparams, error);
+                       if (!type_is_reference (prop_type))
+                               g_free (pparams [0]);
+                       if (!is_ok (error)) {
+                               g_free (name);
+                               goto fail;
+                       }
+               }
+               g_free (name);
+       }
+
+       free_param_data (method->signature, params);
+       if (params != params_buf)
+               mono_gc_free_fixed (params);
+
+       return attr;
+
+fail:
+       free_param_data (method->signature, params);
+       if (params != params_buf)
+               mono_gc_free_fixed (params);
+       return NULL;
+}
+       
+/*
+ * mono_reflection_create_custom_attr_data_args:
+ *
+ *   Create an array of typed and named arguments from the cattr blob given by DATA.
+ * TYPED_ARGS and NAMED_ARGS will contain the objects representing the arguments,
+ * NAMED_ARG_INFO will contain information about the named arguments.
+ */
+void
+mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len, MonoArray **typed_args, MonoArray **named_args, CattrNamedArg **named_arg_info, MonoError *error)
+{
+       MonoArray *typedargs, *namedargs;
+       MonoClass *attrklass;
+       MonoDomain *domain;
+       const char *p = (const char*)data;
+       const char *named;
+       guint32 i, j, num_named;
+       CattrNamedArg *arginfo = NULL;
+
+       *typed_args = NULL;
+       *named_args = NULL;
+       *named_arg_info = NULL;
+
+       mono_error_init (error);
+
+       if (!mono_verifier_verify_cattr_content (image, method, data, len, NULL)) {
+               mono_error_set_generic_error (error, "System.Reflection", "CustomAttributeFormatException", "Binary format of the specified custom attribute was invalid.");
+               return;
+       }
+
+       mono_class_init (method->klass);
+       
+       domain = mono_domain_get ();
+
+       if (len < 2 || read16 (p) != 0x0001) /* Prolog */
+               return;
+
+       typedargs = mono_array_new_checked (domain, mono_get_object_class (), mono_method_signature (method)->param_count, error);
+       return_if_nok (error);
+
+       /* skip prolog */
+       p += 2;
+       for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
+               MonoObject *obj;
+
+               obj = load_cattr_value_boxed (domain, image, mono_method_signature (method)->params [i], p, &p, error);
+               return_if_nok (error);
+               mono_array_setref (typedargs, i, obj);
+       }
+
+       named = p;
+       num_named = read16 (named);
+       namedargs = mono_array_new_checked (domain, mono_get_object_class (), num_named, error);
+       return_if_nok (error);
+       named += 2;
+       attrklass = method->klass;
+
+       arginfo = g_new0 (CattrNamedArg, num_named);
+       *named_arg_info = arginfo;
+
+       for (j = 0; j < num_named; j++) {
+               gint name_len;
+               char *name, named_type, data_type;
+               named_type = *named++;
+               data_type = *named++; /* type of data */
+               if (data_type == MONO_TYPE_SZARRAY)
+                       data_type = *named++;
+               if (data_type == MONO_TYPE_ENUM) {
+                       gint type_len;
+                       char *type_name;
+                       type_len = mono_metadata_decode_blob_size (named, &named);
+                       if (ADDP_IS_GREATER_OR_OVF ((const guchar*)named, type_len, data + len))
+                               goto fail;
+
+                       type_name = (char *)g_malloc (type_len + 1);
+                       memcpy (type_name, named, type_len);
+                       type_name [type_len] = 0;
+                       named += type_len;
+                       /* FIXME: lookup the type and check type consistency */
+                       g_free (type_name);
+               }
+               name_len = mono_metadata_decode_blob_size (named, &named);
+               if (ADDP_IS_GREATER_OR_OVF ((const guchar*)named, name_len, data + len))
+                       goto fail;
+               name = (char *)g_malloc (name_len + 1);
+               memcpy (name, named, name_len);
+               name [name_len] = 0;
+               named += name_len;
+               if (named_type == 0x53) {
+                       MonoObject *obj;
+                       MonoClassField *field = mono_class_get_field_from_name (attrklass, name);
+
+                       if (!field) {
+                               g_free (name);
+                               goto fail;
+                       }
+
+                       arginfo [j].type = field->type;
+                       arginfo [j].field = field;
+
+                       obj = load_cattr_value_boxed (domain, image, field->type, named, &named, error);
+                       if (!is_ok (error)) {
+                               g_free (name);
+                               return;
+                       }
+                       mono_array_setref (namedargs, j, obj);
+
+               } else if (named_type == 0x54) {
+                       MonoObject *obj;
+                       MonoType *prop_type;
+                       MonoProperty *prop = mono_class_get_property_from_name (attrklass, name);
+
+                       if (!prop || !prop->set) {
+                               g_free (name);
+                               goto fail;
+                       }
+
+                       prop_type = prop->get? mono_method_signature (prop->get)->ret :
+                            mono_method_signature (prop->set)->params [mono_method_signature (prop->set)->param_count - 1];
+
+                       arginfo [j].type = prop_type;
+                       arginfo [j].prop = prop;
+
+                       obj = load_cattr_value_boxed (domain, image, prop_type, named, &named, error);
+                       if (!is_ok (error)) {
+                               g_free (name);
+                               return;
+                       }
+                       mono_array_setref (namedargs, j, obj);
+               }
+               g_free (name);
+       }
+
+       *typed_args = typedargs;
+       *named_args = namedargs;
+       return;
+fail:
+       mono_error_set_generic_error (error, "System.Reflection", "CustomAttributeFormatException", "Binary format of the specified custom attribute was invalid.");
+       g_free (arginfo);
+       *named_arg_info = NULL;
+}
+
+static gboolean
+reflection_resolve_custom_attribute_data (MonoReflectionMethod *ref_method, MonoReflectionAssembly *assembly, gpointer data, guint32 len, MonoArray **ctor_args, MonoArray **named_args, MonoError *error)
+{
+       MonoDomain *domain;
+       MonoArray *typedargs, *namedargs;
+       MonoImage *image;
+       MonoMethod *method;
+       CattrNamedArg *arginfo = NULL;
+       int i;
+
+       mono_error_init (error);
+
+       *ctor_args = NULL;
+       *named_args = NULL;
+
+       if (len == 0)
+               return TRUE;
+
+       image = assembly->assembly->image;
+       method = ref_method->method;
+       domain = mono_object_domain (ref_method);
+
+       if (!mono_class_init (method->klass)) {
+               mono_error_set_for_class_failure (error, method->klass);
+               goto leave;
+       }
+
+       mono_reflection_create_custom_attr_data_args (image, method, (const guchar *)data, len, &typedargs, &namedargs, &arginfo, error);
+       if (!is_ok (error))
+               goto leave;
+
+       if (!typedargs || !namedargs)
+               goto leave;
+
+       for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
+               MonoObject *obj = mono_array_get (typedargs, MonoObject*, i);
+               MonoObject *typedarg;
+
+               typedarg = create_cattr_typed_arg (mono_method_signature (method)->params [i], obj, error);
+               if (!is_ok (error))
+                       goto leave;
+               mono_array_setref (typedargs, i, typedarg);
+       }
+
+       for (i = 0; i < mono_array_length (namedargs); ++i) {
+               MonoObject *obj = mono_array_get (namedargs, MonoObject*, i);
+               MonoObject *typedarg, *namedarg, *minfo;
+
+               if (arginfo [i].prop) {
+                       minfo = (MonoObject*)mono_property_get_object_checked (domain, NULL, arginfo [i].prop, error);
+                       if (!minfo)
+                               goto leave;
+               } else {
+                       minfo = (MonoObject*)mono_field_get_object_checked (domain, NULL, arginfo [i].field, error);
+                       if (!is_ok (error))
+                               goto leave;
+               }
+
+               typedarg = create_cattr_typed_arg (arginfo [i].type, obj, error);
+               if (!is_ok (error))
+                       goto leave;
+               namedarg = create_cattr_named_arg (minfo, typedarg, error);
+               if (!is_ok (error))
+                       goto leave;
+
+               mono_array_setref (namedargs, i, namedarg);
+       }
+
+       *ctor_args = typedargs;
+       *named_args = namedargs;
+
+leave:
+       g_free (arginfo);
+       return mono_error_ok (error);
+}
+
+void
+ves_icall_System_Reflection_CustomAttributeData_ResolveArgumentsInternal (MonoReflectionMethod *ref_method, MonoReflectionAssembly *assembly, gpointer data, guint32 len, MonoArray **ctor_args, MonoArray **named_args)
+{
+       MonoError error;
+       (void) reflection_resolve_custom_attribute_data (ref_method, assembly, data, len, ctor_args, named_args, &error);
+       mono_error_set_pending_exception (&error);
+}
+
+static MonoObject*
+create_custom_attr_data (MonoImage *image, MonoCustomAttrEntry *cattr, MonoError *error)
+{
+       static MonoMethod *ctor;
+
+       MonoDomain *domain;
+       MonoObject *attr;
+       void *params [4];
+
+       mono_error_init (error);
+
+       g_assert (image->assembly);
+
+       if (!ctor)
+               ctor = mono_class_get_method_from_name (mono_defaults.customattribute_data_class, ".ctor", 4);
+
+       domain = mono_domain_get ();
+       attr = mono_object_new_checked (domain, mono_defaults.customattribute_data_class, error);
+       return_val_if_nok (error, NULL);
+       params [0] = mono_method_get_object_checked (domain, cattr->ctor, NULL, error);
+       return_val_if_nok (error, NULL);
+       params [1] = mono_assembly_get_object_checked (domain, image->assembly, error);
+       return_val_if_nok (error, NULL);
+       params [2] = (gpointer)&cattr->data;
+       params [3] = &cattr->data_size;
+
+       mono_runtime_invoke_checked (ctor, attr, params, error);
+       return_val_if_nok (error, NULL);
+       return attr;
+}
+
+static MonoArray*
+mono_custom_attrs_construct_by_type (MonoCustomAttrInfo *cinfo, MonoClass *attr_klass, MonoError *error)
+{
+       MonoArray *result;
+       MonoObject *attr;
+       int i, n;
+
+       mono_error_init (error);
+
+       for (i = 0; i < cinfo->num_attrs; ++i) {
+               MonoCustomAttrEntry *centry = &cinfo->attrs[i];
+               if (!centry->ctor) {
+                       /* The cattr type is not finished yet */
+                       /* We should include the type name but cinfo doesn't contain it */
+                       mono_error_set_type_load_name (error, NULL, NULL, "Custom attribute constructor is null because the custom attribute type is not finished yet.");
+                       return NULL;
+               }
+       }
+
+       n = 0;
+       if (attr_klass) {
+               for (i = 0; i < cinfo->num_attrs; ++i) {
+                       MonoMethod *ctor = cinfo->attrs[i].ctor;
+                       g_assert (ctor);
+                       if (mono_class_is_assignable_from (attr_klass, ctor->klass))
+                               n++;
+               }
+       } else {
+               n = cinfo->num_attrs;
+       }
+
+       result = mono_array_new_cached (mono_domain_get (), mono_defaults.attribute_class, n, error);
+       return_val_if_nok (error, NULL);
+       n = 0;
+       for (i = 0; i < cinfo->num_attrs; ++i) {
+               MonoCustomAttrEntry *centry = &cinfo->attrs [i];
+               if (!attr_klass || mono_class_is_assignable_from (attr_klass, centry->ctor->klass)) {
+                       attr = create_custom_attr (cinfo->image, centry->ctor, centry->data, centry->data_size, error);
+                       if (!mono_error_ok (error))
+                               return result;
+                       mono_array_setref (result, n, attr);
+                       n ++;
+               }
+       }
+       return result;
+}
+
+MonoArray*
+mono_custom_attrs_construct (MonoCustomAttrInfo *cinfo)
+{
+       MonoError error;
+       MonoArray *result = mono_custom_attrs_construct_by_type (cinfo, NULL, &error);
+       mono_error_assert_ok (&error); /*FIXME proper error handling*/
+
+       return result;
+}
+
+static MonoArray*
+mono_custom_attrs_data_construct (MonoCustomAttrInfo *cinfo, MonoError *error)
+{
+       MonoArray *result;
+       MonoObject *attr;
+       int i;
+       
+       mono_error_init (error);
+       result = mono_array_new_checked (mono_domain_get (), mono_defaults.customattribute_data_class, cinfo->num_attrs, error);
+       return_val_if_nok (error, NULL);
+       for (i = 0; i < cinfo->num_attrs; ++i) {
+               attr = create_custom_attr_data (cinfo->image, &cinfo->attrs [i], error);
+               return_val_if_nok (error, NULL);
+               mono_array_setref (result, i, attr);
+       }
+       return result;
+}
+
+/**
+ * mono_custom_attrs_from_index:
+ *
+ * Returns: NULL if no attributes are found or if a loading error occurs.
+ */
+MonoCustomAttrInfo*
+mono_custom_attrs_from_index (MonoImage *image, guint32 idx)
+{
+       MonoError error;
+       MonoCustomAttrInfo *result = mono_custom_attrs_from_index_checked (image, idx, &error);
+       mono_error_cleanup (&error);
+       return result;
+}
+/**
+ * mono_custom_attrs_from_index_checked:
+ *
+ * Returns: NULL if no attributes are found.  On error returns NULL and sets @error.
+ */
+MonoCustomAttrInfo*
+mono_custom_attrs_from_index_checked (MonoImage *image, guint32 idx, MonoError *error)
+{
+       guint32 mtoken, i, len;
+       guint32 cols [MONO_CUSTOM_ATTR_SIZE];
+       MonoTableInfo *ca;
+       MonoCustomAttrInfo *ainfo;
+       GList *tmp, *list = NULL;
+       const char *data;
+       MonoCustomAttrEntry* attr;
+
+       mono_error_init (error);
+
+       ca = &image->tables [MONO_TABLE_CUSTOMATTRIBUTE];
+
+       i = mono_metadata_custom_attrs_from_index (image, idx);
+       if (!i)
+               return NULL;
+       i --;
+       while (i < ca->rows) {
+               if (mono_metadata_decode_row_col (ca, i, MONO_CUSTOM_ATTR_PARENT) != idx)
+                       break;
+               list = g_list_prepend (list, GUINT_TO_POINTER (i));
+               ++i;
+       }
+       len = g_list_length (list);
+       if (!len)
+               return NULL;
+       ainfo = (MonoCustomAttrInfo *)g_malloc0 (MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * len);
+       ainfo->num_attrs = len;
+       ainfo->image = image;
+       for (i = len, tmp = list; i != 0; --i, tmp = tmp->next) {
+               mono_metadata_decode_row (ca, GPOINTER_TO_UINT (tmp->data), cols, MONO_CUSTOM_ATTR_SIZE);
+               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_error ("Unknown table for custom attr type %08x", cols [MONO_CUSTOM_ATTR_TYPE]);
+                       break;
+               }
+               attr = &ainfo->attrs [i - 1];
+               attr->ctor = mono_get_method_checked (image, mtoken, NULL, NULL, error);
+               if (!attr->ctor) {
+                       g_warning ("Can't find custom attr constructor image: %s mtoken: 0x%08x due to %s", image->name, mtoken, mono_error_get_message (error));
+                       g_list_free (list);
+                       g_free (ainfo);
+                       return NULL;
+               }
+
+               if (!mono_verifier_verify_cattr_blob (image, cols [MONO_CUSTOM_ATTR_VALUE], NULL)) {
+                       /*FIXME raising an exception here doesn't make any sense*/
+                       g_warning ("Invalid custom attribute blob on image %s for index %x", image->name, idx);
+                       g_list_free (list);
+                       g_free (ainfo);
+                       return NULL;
+               }
+               data = mono_metadata_blob_heap (image, cols [MONO_CUSTOM_ATTR_VALUE]);
+               attr->data_size = mono_metadata_decode_value (data, &data);
+               attr->data = (guchar*)data;
+       }
+       g_list_free (list);
+
+       return ainfo;
+}
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_method (MonoMethod *method)
+{
+       MonoError error;
+       MonoCustomAttrInfo* result = mono_custom_attrs_from_method_checked  (method, &error);
+       mono_error_cleanup (&error); /* FIXME want a better API that doesn't swallow the error */
+       return result;
+}
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_method_checked (MonoMethod *method, MonoError *error)
+{
+       guint32 idx;
+
+       mono_error_init (error);
+
+       /*
+        * An instantiated method has the same cattrs as the generic method definition.
+        *
+        * LAMESPEC: The .NET SRE throws an exception for instantiations of generic method builders
+        *           Note that this stanza is not necessary for non-SRE types, but it's a micro-optimization
+        */
+       if (method->is_inflated)
+               method = ((MonoMethodInflated *) method)->declaring;
+       
+       if (method_is_dynamic (method) || image_is_dynamic (method->klass->image))
+               return lookup_custom_attr (method->klass->image, method);
+
+       if (!method->token)
+               /* Synthetic methods */
+               return NULL;
+
+       idx = mono_method_get_index (method);
+       idx <<= MONO_CUSTOM_ATTR_BITS;
+       idx |= MONO_CUSTOM_ATTR_METHODDEF;
+       return mono_custom_attrs_from_index_checked (method->klass->image, idx, error);
+}
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_class (MonoClass *klass)
+{
+       MonoError error;
+       MonoCustomAttrInfo *result = mono_custom_attrs_from_class_checked (klass, &error);
+       mono_error_cleanup (&error);
+       return result;
+}
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_class_checked (MonoClass *klass, MonoError *error)
+{
+       guint32 idx;
+
+       mono_error_init (error);
+
+       if (klass->generic_class)
+               klass = klass->generic_class->container_class;
+
+       if (image_is_dynamic (klass->image))
+               return lookup_custom_attr (klass->image, klass);
+
+       if (klass->byval_arg.type == MONO_TYPE_VAR || klass->byval_arg.type == MONO_TYPE_MVAR) {
+               idx = mono_metadata_token_index (klass->sizes.generic_param_token);
+               idx <<= MONO_CUSTOM_ATTR_BITS;
+               idx |= MONO_CUSTOM_ATTR_GENERICPAR;
+       } else {
+               idx = mono_metadata_token_index (klass->type_token);
+               idx <<= MONO_CUSTOM_ATTR_BITS;
+               idx |= MONO_CUSTOM_ATTR_TYPEDEF;
+       }
+       return mono_custom_attrs_from_index_checked (klass->image, idx, error);
+}
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_assembly (MonoAssembly *assembly)
+{
+       MonoError error;
+       MonoCustomAttrInfo *result = mono_custom_attrs_from_assembly_checked (assembly, &error);
+       mono_error_cleanup (&error);
+       return result;
+}
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_assembly_checked (MonoAssembly *assembly, MonoError *error)
+{
+       guint32 idx;
+       
+       mono_error_init (error);
+
+       if (image_is_dynamic (assembly->image))
+               return lookup_custom_attr (assembly->image, assembly);
+       idx = 1; /* there is only one assembly */
+       idx <<= MONO_CUSTOM_ATTR_BITS;
+       idx |= MONO_CUSTOM_ATTR_ASSEMBLY;
+       return mono_custom_attrs_from_index_checked (assembly->image, idx, error);
+}
+
+static MonoCustomAttrInfo*
+mono_custom_attrs_from_module (MonoImage *image, MonoError *error)
+{
+       guint32 idx;
+       
+       if (image_is_dynamic (image))
+               return lookup_custom_attr (image, image);
+       idx = 1; /* there is only one module */
+       idx <<= MONO_CUSTOM_ATTR_BITS;
+       idx |= MONO_CUSTOM_ATTR_MODULE;
+       return mono_custom_attrs_from_index_checked (image, idx, error);
+}
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_property (MonoClass *klass, MonoProperty *property)
+{
+       MonoError error;
+       MonoCustomAttrInfo * result = mono_custom_attrs_from_property_checked (klass, property, &error);
+       mono_error_cleanup (&error);
+       return result;
+}
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_property_checked (MonoClass *klass, MonoProperty *property, MonoError *error)
+{
+       guint32 idx;
+       
+       if (image_is_dynamic (klass->image)) {
+               property = mono_metadata_get_corresponding_property_from_generic_type_definition (property);
+               return lookup_custom_attr (klass->image, property);
+       }
+       idx = find_property_index (klass, property);
+       idx <<= MONO_CUSTOM_ATTR_BITS;
+       idx |= MONO_CUSTOM_ATTR_PROPERTY;
+       return mono_custom_attrs_from_index_checked (klass->image, idx, error);
+}
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_event (MonoClass *klass, MonoEvent *event)
+{
+       MonoError error;
+       MonoCustomAttrInfo * result = mono_custom_attrs_from_event_checked (klass, event, &error);
+       mono_error_cleanup (&error);
+       return result;
+}
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_event_checked (MonoClass *klass, MonoEvent *event, MonoError *error)
+{
+       guint32 idx;
+       
+       if (image_is_dynamic (klass->image)) {
+               event = mono_metadata_get_corresponding_event_from_generic_type_definition (event);
+               return lookup_custom_attr (klass->image, event);
+       }
+       idx = find_event_index (klass, event);
+       idx <<= MONO_CUSTOM_ATTR_BITS;
+       idx |= MONO_CUSTOM_ATTR_EVENT;
+       return mono_custom_attrs_from_index_checked (klass->image, idx, error);
+}
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_field (MonoClass *klass, MonoClassField *field)
+{
+       MonoError error;
+       MonoCustomAttrInfo * result = mono_custom_attrs_from_field_checked (klass, field, &error);
+       mono_error_cleanup (&error);
+       return result;
+}
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_field_checked (MonoClass *klass, MonoClassField *field, MonoError *error)
+{
+       guint32 idx;
+       mono_error_init (error);
+
+       if (image_is_dynamic (klass->image)) {
+               field = mono_metadata_get_corresponding_field_from_generic_type_definition (field);
+               return lookup_custom_attr (klass->image, field);
+       }
+       idx = find_field_index (klass, field);
+       idx <<= MONO_CUSTOM_ATTR_BITS;
+       idx |= MONO_CUSTOM_ATTR_FIELDDEF;
+       return mono_custom_attrs_from_index_checked (klass->image, idx, error);
+}
+
+/**
+ * mono_custom_attrs_from_param:
+ * @method: handle to the method that we want to retrieve custom parameter information from
+ * @param: parameter number, where zero represent the return value, and one is the first parameter in the method
+ *
+ * The result must be released with mono_custom_attrs_free().
+ *
+ * Returns: the custom attribute object for the specified parameter, or NULL if there are none.
+ */
+MonoCustomAttrInfo*
+mono_custom_attrs_from_param (MonoMethod *method, guint32 param)
+{
+       MonoError error;
+       MonoCustomAttrInfo *result = mono_custom_attrs_from_param_checked (method, param, &error);
+       mono_error_cleanup (&error);
+       return result;
+}
+
+/**
+ * mono_custom_attrs_from_param_checked:
+ * @method: handle to the method that we want to retrieve custom parameter information from
+ * @param: parameter number, where zero represent the return value, and one is the first parameter in the method
+ * @error: set on error
+ *
+ * The result must be released with mono_custom_attrs_free().
+ *
+ * Returns: the custom attribute object for the specified parameter, or NULL if there are none.  On failure returns NULL and sets @error.
+ */
+MonoCustomAttrInfo*
+mono_custom_attrs_from_param_checked (MonoMethod *method, guint32 param, MonoError *error)
+{
+       MonoTableInfo *ca;
+       guint32 i, idx, method_index;
+       guint32 param_list, param_last, param_pos, found;
+       MonoImage *image;
+       MonoReflectionMethodAux *aux;
+
+       mono_error_init (error);
+
+       /*
+        * An instantiated method has the same cattrs as the generic method definition.
+        *
+        * LAMESPEC: The .NET SRE throws an exception for instantiations of generic method builders
+        *           Note that this stanza is not necessary for non-SRE types, but it's a micro-optimization
+        */
+       if (method->is_inflated)
+               method = ((MonoMethodInflated *) method)->declaring;
+
+       if (image_is_dynamic (method->klass->image)) {
+               MonoCustomAttrInfo *res, *ainfo;
+               int size;
+
+               aux = (MonoReflectionMethodAux *)g_hash_table_lookup (((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
+               if (!aux || !aux->param_cattr)
+                       return NULL;
+
+               /* Need to copy since it will be freed later */
+               ainfo = aux->param_cattr [param];
+               if (!ainfo)
+                       return NULL;
+               size = MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * ainfo->num_attrs;
+               res = (MonoCustomAttrInfo *)g_malloc0 (size);
+               memcpy (res, ainfo, size);
+               return res;
+       }
+
+       image = method->klass->image;
+       method_index = mono_method_get_index (method);
+       if (!method_index)
+               return NULL;
+       ca = &image->tables [MONO_TABLE_METHOD];
+
+       param_list = mono_metadata_decode_row_col (ca, method_index - 1, MONO_METHOD_PARAMLIST);
+       if (method_index == ca->rows) {
+               ca = &image->tables [MONO_TABLE_PARAM];
+               param_last = ca->rows + 1;
+       } else {
+               param_last = mono_metadata_decode_row_col (ca, method_index, MONO_METHOD_PARAMLIST);
+               ca = &image->tables [MONO_TABLE_PARAM];
+       }
+       found = FALSE;
+       for (i = param_list; i < param_last; ++i) {
+               param_pos = mono_metadata_decode_row_col (ca, i - 1, MONO_PARAM_SEQUENCE);
+               if (param_pos == param) {
+                       found = TRUE;
+                       break;
+               }
+       }
+       if (!found)
+               return NULL;
+       idx = i;
+       idx <<= MONO_CUSTOM_ATTR_BITS;
+       idx |= MONO_CUSTOM_ATTR_PARAMDEF;
+       return mono_custom_attrs_from_index_checked (image, idx, error);
+}
+
+gboolean
+mono_custom_attrs_has_attr (MonoCustomAttrInfo *ainfo, MonoClass *attr_klass)
+{
+       int i;
+       for (i = 0; i < ainfo->num_attrs; ++i) {
+               MonoClass *klass = ainfo->attrs [i].ctor->klass;
+               if (mono_class_has_parent (klass, attr_klass) || (MONO_CLASS_IS_INTERFACE (attr_klass) && mono_class_is_assignable_from (attr_klass, klass)))
+                       return TRUE;
+       }
+       return FALSE;
+}
+
+MonoObject*
+mono_custom_attrs_get_attr (MonoCustomAttrInfo *ainfo, MonoClass *attr_klass)
+{
+       MonoError error;
+       MonoObject *res = mono_custom_attrs_get_attr_checked (ainfo, attr_klass, &error);
+       mono_error_assert_ok (&error); /*FIXME proper error handling*/
+       return res;
+}
+
+MonoObject*
+mono_custom_attrs_get_attr_checked (MonoCustomAttrInfo *ainfo, MonoClass *attr_klass, MonoError *error)
+{
+       int i, attr_index;
+       MonoArray *attrs;
+
+       mono_error_init (error);
+
+       attr_index = -1;
+       for (i = 0; i < ainfo->num_attrs; ++i) {
+               MonoClass *klass = ainfo->attrs [i].ctor->klass;
+               if (mono_class_has_parent (klass, attr_klass)) {
+                       attr_index = i;
+                       break;
+               }
+       }
+       if (attr_index == -1)
+               return NULL;
+
+       attrs = mono_custom_attrs_construct_by_type (ainfo, NULL, error);
+       if (!mono_error_ok (error))
+               return NULL;
+       return mono_array_get (attrs, MonoObject*, attr_index);
+}
+
+/*
+ * mono_reflection_get_custom_attrs_info:
+ * @obj: a reflection object handle
+ *
+ * Return the custom attribute info for attributes defined for the
+ * reflection handle @obj. The objects.
+ *
+ * FIXME this function leaks like a sieve for SRE objects.
+ */
+MonoCustomAttrInfo*
+mono_reflection_get_custom_attrs_info (MonoObject *obj)
+{
+       MonoError error;
+       MonoCustomAttrInfo *result = mono_reflection_get_custom_attrs_info_checked (obj, &error);
+       mono_error_assert_ok (&error);
+       return result;
+}
+
+/**
+ * mono_reflection_get_custom_attrs_info_checked:
+ * @obj: a reflection object handle
+ * @error: set on error
+ *
+ * Return the custom attribute info for attributes defined for the
+ * reflection handle @obj. The objects.
+ *
+ * On failure returns NULL and sets @error.
+ *
+ * FIXME this function leaks like a sieve for SRE objects.
+ */
+MonoCustomAttrInfo*
+mono_reflection_get_custom_attrs_info_checked (MonoObject *obj, MonoError *error)
+{
+       MonoClass *klass;
+       MonoCustomAttrInfo *cinfo = NULL;
+       
+       mono_error_init (error);
+
+       klass = obj->vtable->klass;
+       if (klass == mono_defaults.runtimetype_class) {
+               MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
+               return_val_if_nok (error, NULL);
+               klass = mono_class_from_mono_type (type);
+               /*We cannot mono_class_init the class from which we'll load the custom attributes since this must work with broken types.*/
+               cinfo = mono_custom_attrs_from_class_checked (klass, error);
+               return_val_if_nok (error, NULL);
+       } else if (strcmp ("Assembly", klass->name) == 0 || strcmp ("MonoAssembly", klass->name) == 0) {
+               MonoReflectionAssembly *rassembly = (MonoReflectionAssembly*)obj;
+               cinfo = mono_custom_attrs_from_assembly_checked (rassembly->assembly, error);
+               return_val_if_nok (error, NULL);
+       } else if (strcmp ("Module", klass->name) == 0 || strcmp ("MonoModule", klass->name) == 0) {
+               MonoReflectionModule *module = (MonoReflectionModule*)obj;
+               cinfo = mono_custom_attrs_from_module (module->image, error);
+               return_val_if_nok (error, NULL);
+       } else if (strcmp ("MonoProperty", klass->name) == 0) {
+               MonoReflectionProperty *rprop = (MonoReflectionProperty*)obj;
+               cinfo = mono_custom_attrs_from_property_checked (rprop->property->parent, rprop->property, error);
+               return_val_if_nok (error, NULL);
+       } else if (strcmp ("MonoEvent", klass->name) == 0) {
+               MonoReflectionMonoEvent *revent = (MonoReflectionMonoEvent*)obj;
+               cinfo = mono_custom_attrs_from_event_checked (revent->event->parent, revent->event, error);
+               return_val_if_nok (error, NULL);
+       } else if (strcmp ("MonoField", klass->name) == 0) {
+               MonoReflectionField *rfield = (MonoReflectionField*)obj;
+               cinfo = mono_custom_attrs_from_field_checked (rfield->field->parent, rfield->field, error);
+               return_val_if_nok (error, NULL);
+       } else if ((strcmp ("MonoMethod", klass->name) == 0) || (strcmp ("MonoCMethod", klass->name) == 0)) {
+               MonoReflectionMethod *rmethod = (MonoReflectionMethod*)obj;
+               cinfo = mono_custom_attrs_from_method_checked (rmethod->method, error);
+               return_val_if_nok (error, NULL);
+       } else if ((strcmp ("MonoGenericMethod", klass->name) == 0) || (strcmp ("MonoGenericCMethod", klass->name) == 0)) {
+               MonoReflectionMethod *rmethod = (MonoReflectionMethod*)obj;
+               cinfo = mono_custom_attrs_from_method_checked (rmethod->method, error);
+               return_val_if_nok (error, NULL);
+       } else if (strcmp ("ParameterInfo", klass->name) == 0 || strcmp ("MonoParameterInfo", klass->name) == 0) {
+               MonoReflectionParameter *param = (MonoReflectionParameter*)obj;
+               MonoClass *member_class = mono_object_class (param->MemberImpl);
+               if (mono_class_is_reflection_method_or_constructor (member_class)) {
+                       MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
+                       cinfo = mono_custom_attrs_from_param_checked (rmethod->method, param->PositionImpl + 1, error);
+                       return_val_if_nok (error, NULL);
+               } else if (mono_is_sr_mono_property (member_class)) {
+                       MonoReflectionProperty *prop = (MonoReflectionProperty *)param->MemberImpl;
+                       MonoMethod *method;
+                       if (!(method = prop->property->get))
+                               method = prop->property->set;
+                       g_assert (method);
+
+                       cinfo = mono_custom_attrs_from_param_checked (method, param->PositionImpl + 1, error);
+                       return_val_if_nok (error, NULL);
+               } 
+#ifndef DISABLE_REFLECTION_EMIT
+               else if (mono_is_sre_method_on_tb_inst (member_class)) {/*XXX This is a workaround for Compiler Context*/
+                       MonoMethod *method = mono_reflection_method_on_tb_inst_get_handle ((MonoReflectionMethodOnTypeBuilderInst*)param->MemberImpl, error);
+                       return_val_if_nok (error, NULL);
+                       cinfo = mono_custom_attrs_from_param_checked (method, param->PositionImpl + 1, error);
+                       return_val_if_nok (error, NULL);
+               } else if (mono_is_sre_ctor_on_tb_inst (member_class)) { /*XX This is a workaround for Compiler Context*/
+                       MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)param->MemberImpl;
+                       MonoMethod *method = NULL;
+                       if (mono_is_sre_ctor_builder (mono_object_class (c->cb)))
+                               method = ((MonoReflectionCtorBuilder *)c->cb)->mhandle;
+                       else if (mono_is_sr_mono_cmethod (mono_object_class (c->cb)))
+                               method = ((MonoReflectionMethod *)c->cb)->method;
+                       else
+                               g_error ("mono_reflection_get_custom_attrs_info:: can't handle a CTBI with base_method of type %s", mono_type_get_full_name (member_class));
+
+                       cinfo = mono_custom_attrs_from_param_checked (method, param->PositionImpl + 1, error);
+                       return_val_if_nok (error, NULL);
+               } 
+#endif
+               else {
+                       char *type_name = mono_type_get_full_name (member_class);
+                       mono_error_set_not_supported (error,
+                                                     "Custom attributes on a ParamInfo with member %s are not supported",
+                                                     type_name);
+                       g_free (type_name);
+                       return NULL;
+               }
+       } else if (strcmp ("AssemblyBuilder", klass->name) == 0) {
+               MonoReflectionAssemblyBuilder *assemblyb = (MonoReflectionAssemblyBuilder*)obj;
+               cinfo = mono_custom_attrs_from_builders (NULL, assemblyb->assembly.assembly->image, assemblyb->cattrs);
+       } else if (strcmp ("TypeBuilder", klass->name) == 0) {
+               MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
+               cinfo = mono_custom_attrs_from_builders (NULL, &tb->module->dynamic_image->image, tb->cattrs);
+       } else if (strcmp ("ModuleBuilder", klass->name) == 0) {
+               MonoReflectionModuleBuilder *mb = (MonoReflectionModuleBuilder*)obj;
+               cinfo = mono_custom_attrs_from_builders (NULL, &mb->dynamic_image->image, mb->cattrs);
+       } else if (strcmp ("ConstructorBuilder", klass->name) == 0) {
+               MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder*)obj;
+               cinfo = mono_custom_attrs_from_builders (NULL, cb->mhandle->klass->image, cb->cattrs);
+       } else if (strcmp ("MethodBuilder", klass->name) == 0) {
+               MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)obj;
+               cinfo = mono_custom_attrs_from_builders (NULL, mb->mhandle->klass->image, mb->cattrs);
+       } else if (strcmp ("FieldBuilder", klass->name) == 0) {
+               MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder*)obj;
+               cinfo = mono_custom_attrs_from_builders (NULL, &((MonoReflectionTypeBuilder*)fb->typeb)->module->dynamic_image->image, fb->cattrs);
+       } else if (strcmp ("MonoGenericClass", klass->name) == 0) {
+               MonoReflectionGenericClass *gclass = (MonoReflectionGenericClass*)obj;
+               cinfo = mono_reflection_get_custom_attrs_info_checked ((MonoObject*)gclass->generic_type, error);
+               return_val_if_nok (error, NULL);
+       } else { /* handle other types here... */
+               g_error ("get custom attrs not yet supported for %s", klass->name);
+       }
+
+       return cinfo;
+}
+
+/*
+ * mono_reflection_get_custom_attrs_by_type:
+ * @obj: a reflection object handle
+ *
+ * Return an array with all the custom attributes defined of the
+ * reflection handle @obj. If @attr_klass is non-NULL, only custom attributes 
+ * of that type are returned. The objects are fully build. Return NULL if a loading error
+ * occurs.
+ */
+MonoArray*
+mono_reflection_get_custom_attrs_by_type (MonoObject *obj, MonoClass *attr_klass, MonoError *error)
+{
+       MonoArray *result;
+       MonoCustomAttrInfo *cinfo;
+
+       mono_error_init (error);
+
+       cinfo = mono_reflection_get_custom_attrs_info_checked (obj, error);
+       return_val_if_nok (error, NULL);
+       if (cinfo) {
+               result = mono_custom_attrs_construct_by_type (cinfo, attr_klass, error);
+               if (!cinfo->cached)
+                       mono_custom_attrs_free (cinfo);
+               if (!result)
+                       return NULL;
+       } else {
+               result = mono_array_new_cached (mono_domain_get (), mono_defaults.attribute_class, 0, error);
+       }
+
+       return result;
+}
+
+/*
+ * mono_reflection_get_custom_attrs:
+ * @obj: a reflection object handle
+ *
+ * Return an array with all the custom attributes defined of the
+ * reflection handle @obj. The objects are fully build. Return NULL if a loading error
+ * occurs.
+ */
+MonoArray*
+mono_reflection_get_custom_attrs (MonoObject *obj)
+{
+       MonoError error;
+
+       return mono_reflection_get_custom_attrs_by_type (obj, NULL, &error);
+}
+
+/*
+ * mono_reflection_get_custom_attrs_data:
+ * @obj: a reflection obj handle
+ *
+ * Returns an array of System.Reflection.CustomAttributeData,
+ * which include information about attributes reflected on
+ * types loaded using the Reflection Only methods
+ */
+MonoArray*
+mono_reflection_get_custom_attrs_data (MonoObject *obj)
+{
+       MonoError error;
+       MonoArray* result;
+       result = mono_reflection_get_custom_attrs_data_checked (obj, &error);
+       mono_error_cleanup (&error);
+       return result;
+}
+
+/*
+ * mono_reflection_get_custom_attrs_data_checked:
+ * @obj: a reflection obj handle
+ * @error: set on error
+ *
+ * Returns an array of System.Reflection.CustomAttributeData,
+ * which include information about attributes reflected on
+ * types loaded using the Reflection Only methods
+ */
+MonoArray*
+mono_reflection_get_custom_attrs_data_checked (MonoObject *obj, MonoError *error)
+{
+       MonoArray *result;
+       MonoCustomAttrInfo *cinfo;
+
+       mono_error_init (error);
+
+       cinfo = mono_reflection_get_custom_attrs_info_checked (obj, error);
+       return_val_if_nok (error, NULL);
+       if (cinfo) {
+               result = mono_custom_attrs_data_construct (cinfo, error);
+               if (!cinfo->cached)
+                       mono_custom_attrs_free (cinfo);
+               return_val_if_nok (error, NULL);
+       } else 
+               result = mono_array_new_checked (mono_domain_get (), mono_defaults.customattribute_data_class, 0, error);
+
+       return result;
+}
index e385adadfd5c1b29b241952e86dd661a1e78298b..500a87da63c77a146a2c5afd63e62a8d600ace00 100644 (file)
@@ -700,4 +700,8 @@ mono_runtime_init_checked (MonoDomain *domain, MonoThreadStartCB start_cb, MonoT
 void
 mono_context_init_checked (MonoDomain *domain, MonoError *error);
 
+gboolean
+mono_assembly_get_reference_assembly_attribute (MonoAssembly *assembly, MonoError *error);
+
+
 #endif /* __MONO_METADATA_DOMAIN_INTERNALS_H__ */
index d564151b7df43e403c7a72cb7f58ca3810e3a468..6cfd0dbbb9ea31c1a6ff8ba24d0db0e423381f01 100644 (file)
@@ -43,7 +43,6 @@
 #include <metadata/threads.h>
 #include <metadata/profiler-private.h>
 #include <mono/metadata/coree.h>
-#include <mono/utils/w32handle.h>
 
 //#define DEBUG_DOMAIN_UNLOAD 1
 
@@ -809,6 +808,16 @@ 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_get_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;
 }
 
@@ -895,7 +904,6 @@ mono_cleanup (void)
 
 #ifndef HOST_WIN32
        wapi_cleanup ();
-       mono_w32handle_cleanup ();
 #endif
 }
 
diff --git a/mono/metadata/dynamic-image-internals.h b/mono/metadata/dynamic-image-internals.h
new file mode 100644 (file)
index 0000000..e012168
--- /dev/null
@@ -0,0 +1,44 @@
+/* 
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#ifndef __MONO_METADATA_DYNAMIC_IMAGE_INTERNALS_H__
+#define __MONO_METADATA_DYNAMIC_IMAGE_INTERNALS_H__
+
+#include <mono/metadata/object.h>
+#include <mono/metadata/metadata-internals.h>
+
+typedef struct {
+       guint32 import_lookup_table;
+       guint32 timestamp;
+       guint32 forwarder;
+       guint32 name_rva;
+       guint32 import_address_table_rva;
+} MonoIDT;
+
+typedef struct {
+       guint32 name_rva;
+       guint32 flags;
+} MonoILT;
+
+
+void
+mono_dynamic_images_init (void);
+
+void
+mono_dynamic_image_register_token (MonoDynamicImage *assembly, guint32 token, MonoObject *obj);
+
+gboolean
+mono_dynamic_image_is_valid_token (MonoDynamicImage *image, guint32 token);
+
+MonoDynamicImage*
+mono_dynamic_image_create (MonoDynamicAssembly *assembly, char *assembly_name, char *module_name);
+
+guint32
+mono_dynamic_image_add_to_blob_cached (MonoDynamicImage *assembly, char *b1, int s1, char *b2, int s2);
+
+void
+mono_dynimage_alloc_table (MonoDynamicTable *table, guint nrows);
+
+#endif  /* __MONO_METADATA_DYNAMIC_IMAGE_INTERNALS_H__ */
+
diff --git a/mono/metadata/dynamic-image.c b/mono/metadata/dynamic-image.c
new file mode 100644 (file)
index 0000000..17f0f8e
--- /dev/null
@@ -0,0 +1,562 @@
+/*
+ * dynamic-image.c: Images created at runtime.
+ *   
+ * 
+ * Author:
+ *   Paolo Molaro (lupus@ximian.com)
+ *
+ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
+ * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
+ * Copyright 2011 Rodrigo Kumpera
+ * 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>
+#include "mono/metadata/object.h"
+#include "mono/metadata/dynamic-image-internals.h"
+#include "mono/metadata/dynamic-stream-internals.h"
+#include "mono/metadata/gc-internals.h"
+#include "mono/metadata/metadata-internals.h"
+#include "mono/metadata/profiler-private.h"
+#include "mono/metadata/reflection-internals.h"
+#include "mono/metadata/sre-internals.h"
+#include "mono/utils/checked-build.h"
+#include "mono/utils/mono-error-internals.h"
+#include "mono/utils/mono-os-mutex.h"
+
+const unsigned char table_sizes [MONO_TABLE_NUM] = {
+       MONO_MODULE_SIZE,
+       MONO_TYPEREF_SIZE,
+       MONO_TYPEDEF_SIZE,
+       0,
+       MONO_FIELD_SIZE,
+       0,
+       MONO_METHOD_SIZE,
+       0,
+       MONO_PARAM_SIZE,
+       MONO_INTERFACEIMPL_SIZE,
+       MONO_MEMBERREF_SIZE,    /* 0x0A */
+       MONO_CONSTANT_SIZE,
+       MONO_CUSTOM_ATTR_SIZE,
+       MONO_FIELD_MARSHAL_SIZE,
+       MONO_DECL_SECURITY_SIZE,
+       MONO_CLASS_LAYOUT_SIZE,
+       MONO_FIELD_LAYOUT_SIZE, /* 0x10 */
+       MONO_STAND_ALONE_SIGNATURE_SIZE,
+       MONO_EVENT_MAP_SIZE,
+       0,
+       MONO_EVENT_SIZE,
+       MONO_PROPERTY_MAP_SIZE,
+       0,
+       MONO_PROPERTY_SIZE,
+       MONO_METHOD_SEMA_SIZE,
+       MONO_METHODIMPL_SIZE,
+       MONO_MODULEREF_SIZE,    /* 0x1A */
+       MONO_TYPESPEC_SIZE,
+       MONO_IMPLMAP_SIZE,      
+       MONO_FIELD_RVA_SIZE,
+       0,
+       0,
+       MONO_ASSEMBLY_SIZE,     /* 0x20 */
+       MONO_ASSEMBLY_PROCESSOR_SIZE,
+       MONO_ASSEMBLYOS_SIZE,
+       MONO_ASSEMBLYREF_SIZE,
+       MONO_ASSEMBLYREFPROC_SIZE,
+       MONO_ASSEMBLYREFOS_SIZE,
+       MONO_FILE_SIZE,
+       MONO_EXP_TYPE_SIZE,
+       MONO_MANIFEST_SIZE,
+       MONO_NESTED_CLASS_SIZE,
+
+       MONO_GENERICPARAM_SIZE, /* 0x2A */
+       MONO_METHODSPEC_SIZE,
+       MONO_GENPARCONSTRAINT_SIZE
+
+};
+
+// The dynamic images list is only needed to support the mempool reference tracking feature in checked-build.
+static GPtrArray *dynamic_images;
+static mono_mutex_t dynamic_images_mutex;
+
+static inline void
+dynamic_images_lock (void)
+{
+       mono_os_mutex_lock (&dynamic_images_mutex);
+}
+
+static inline void
+dynamic_images_unlock (void)
+{
+       mono_os_mutex_unlock (&dynamic_images_mutex);
+}
+
+void
+mono_dynamic_images_init (void)
+{
+       mono_os_mutex_init (&dynamic_images_mutex);
+}
+
+#ifndef DISABLE_REFLECTION_EMIT
+static void
+string_heap_init (MonoDynamicStream *sh)
+{
+       mono_dynstream_init (sh);
+}
+#endif
+
+#ifndef DISABLE_REFLECTION_EMIT
+static int
+mono_blob_entry_hash (const char* str)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       guint len, h;
+       const char *end;
+       len = mono_metadata_decode_blob_size (str, &str);
+       if (len > 0) {
+               end = str + len;
+               h = *str;
+               for (str += 1; str < end; str++)
+                       h = (h << 5) - h + *str;
+               return h;
+       } else {
+               return 0;
+       }
+}
+
+static gboolean
+mono_blob_entry_equal (const char *str1, const char *str2) {
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       int len, len2;
+       const char *end1;
+       const char *end2;
+       len = mono_metadata_decode_blob_size (str1, &end1);
+       len2 = mono_metadata_decode_blob_size (str2, &end2);
+       if (len != len2)
+               return 0;
+       return memcmp (end1, end2, len) == 0;
+}
+#endif
+
+
+/**
+ * mono_find_dynamic_image_owner:
+ *
+ * Find the dynamic image, if any, which a given pointer is located in the memory of.
+ */
+MonoImage *
+mono_find_dynamic_image_owner (void *ptr)
+{
+       MonoImage *owner = NULL;
+       int i;
+
+       dynamic_images_lock ();
+
+       if (dynamic_images)
+       {
+               for (i = 0; !owner && i < dynamic_images->len; ++i) {
+                       MonoImage *image = (MonoImage *)g_ptr_array_index (dynamic_images, i);
+                       if (mono_mempool_contains_addr (image->mempool, ptr))
+                               owner = image;
+               }
+       }
+
+       dynamic_images_unlock ();
+
+       return owner;
+}
+
+static inline void
+dynamic_image_lock (MonoDynamicImage *image)
+{
+       MONO_ENTER_GC_SAFE;
+       mono_image_lock ((MonoImage*)image);
+       MONO_EXIT_GC_SAFE;
+}
+
+static inline void
+dynamic_image_unlock (MonoDynamicImage *image)
+{
+       mono_image_unlock ((MonoImage*)image);
+}
+
+void
+mono_dynamic_image_register_token (MonoDynamicImage *assembly, guint32 token, MonoObject *obj)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       dynamic_image_lock (assembly);
+       mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), obj);
+       dynamic_image_unlock (assembly);
+}
+
+static MonoObject*
+lookup_dyn_token (MonoDynamicImage *assembly, guint32 token)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       MonoObject *obj;
+
+       dynamic_image_lock (assembly);
+       obj = (MonoObject *)mono_g_hash_table_lookup (assembly->tokens, GUINT_TO_POINTER (token));
+       dynamic_image_unlock (assembly);
+
+       return obj;
+}
+
+/**
+ * 
+ * mono_dynamic_image_is_valid_token:
+ * 
+ * Returns TRUE if token is valid in the given image.
+ * 
+ */
+gboolean
+mono_dynamic_image_is_valid_token (MonoDynamicImage *image, guint32 token)
+{
+       return lookup_dyn_token (image, token) != NULL;
+}
+
+#ifndef DISABLE_REFLECTION_EMIT
+
+#endif /* DISABLE_REFLECTION_EMIT */
+
+#ifndef DISABLE_REFLECTION_EMIT
+/**
+ * mono_reflection_lookup_dynamic_token:
+ *
+ * Finish the Builder object pointed to by TOKEN and return the corresponding
+ * runtime structure. If HANDLE_CLASS is not NULL, it is set to the class required by 
+ * mono_ldtoken. If valid_token is TRUE, assert if it is not found in the token->object
+ * mapping table.
+ *
+ * LOCKING: Take the loader lock
+ */
+gpointer
+mono_reflection_lookup_dynamic_token (MonoImage *image, guint32 token, gboolean valid_token, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
+{
+       MonoDynamicImage *assembly = (MonoDynamicImage*)image;
+       MonoObject *obj;
+       MonoClass *klass;
+
+       mono_error_init (error);
+       
+       obj = lookup_dyn_token (assembly, token);
+       if (!obj) {
+               if (valid_token)
+                       g_error ("Could not find required dynamic token 0x%08x", token);
+               else {
+                       mono_error_set_execution_engine (error, "Could not find dynamic token 0x%08x", token);
+                       return NULL;
+               }
+       }
+
+       if (!handle_class)
+               handle_class = &klass;
+       gpointer result = mono_reflection_resolve_object (image, obj, handle_class, context, error);
+       return result;
+}
+
+/*
+ * mono_image_register_token:
+ *
+ *   Register the TOKEN->OBJ mapping in the mapping table in ASSEMBLY. This is required for
+ * the Module.ResolveXXXToken () methods to work.
+ */
+void
+mono_image_register_token (MonoDynamicImage *assembly, guint32 token, MonoObject *obj)
+{
+       MonoObject *prev;
+
+       dynamic_image_lock (assembly);
+       prev = (MonoObject *)mono_g_hash_table_lookup (assembly->tokens, GUINT_TO_POINTER (token));
+       if (prev) {
+               /* There could be multiple MethodInfo objects with the same token */
+               //g_assert (prev == obj);
+       } else {
+               mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), obj);
+       }
+       dynamic_image_unlock (assembly);
+}
+
+#else /* DISABLE_REFLECTION_EMIT */
+
+gpointer
+mono_reflection_lookup_dynamic_token (MonoImage *image, guint32 token, gboolean valid_token, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
+{
+       mono_error_init (error);
+       return NULL;
+}
+
+void
+mono_image_register_token (MonoDynamicImage *assembly, guint32 token, MonoObject *obj)
+{
+}
+
+#endif /* DISABLE_REFLECTION_EMIT */
+
+#ifndef DISABLE_REFLECTION_EMIT
+MonoDynamicImage*
+mono_dynamic_image_create (MonoDynamicAssembly *assembly, char *assembly_name, char *module_name)
+{
+       static const guchar entrycode [16] = {0xff, 0x25, 0};
+       MonoDynamicImage *image;
+       int i;
+
+       const char *version;
+
+       if (!strcmp (mono_get_runtime_info ()->framework_version, "2.1"))
+               version = "v2.0.50727"; /* HACK: SL 2 enforces the .net 2 metadata version */
+       else
+               version = mono_get_runtime_info ()->runtime_version;
+
+#if HAVE_BOEHM_GC
+       /* The MonoGHashTable's need GC tracking */
+       image = (MonoDynamicImage *)GC_MALLOC (sizeof (MonoDynamicImage));
+#else
+       image = g_new0 (MonoDynamicImage, 1);
+#endif
+
+       mono_profiler_module_event (&image->image, MONO_PROFILE_START_LOAD);
+       
+       /*g_print ("created image %p\n", image);*/
+       /* keep in sync with image.c */
+       image->image.name = assembly_name;
+       image->image.assembly_name = image->image.name; /* they may be different */
+       image->image.module_name = module_name;
+       image->image.version = g_strdup (version);
+       image->image.md_version_major = 1;
+       image->image.md_version_minor = 1;
+       image->image.dynamic = TRUE;
+
+       image->image.references = g_new0 (MonoAssembly*, 1);
+       image->image.references [0] = NULL;
+
+       mono_image_init (&image->image);
+
+       image->token_fixups = mono_g_hash_table_new_type ((GHashFunc)mono_object_hash, NULL, MONO_HASH_KEY_GC, MONO_ROOT_SOURCE_REFLECTION, "dynamic module token fixups table");
+       image->method_to_table_idx = g_hash_table_new (NULL, NULL);
+       image->field_to_table_idx = g_hash_table_new (NULL, NULL);
+       image->method_aux_hash = g_hash_table_new (NULL, NULL);
+       image->vararg_aux_hash = g_hash_table_new (NULL, NULL);
+       image->handleref = g_hash_table_new (NULL, NULL);
+       image->handleref_managed = mono_g_hash_table_new_type ((GHashFunc)mono_object_hash, NULL, MONO_HASH_KEY_GC, MONO_ROOT_SOURCE_REFLECTION, "dynamic module reference-to-token table");
+       image->tokens = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_REFLECTION, "dynamic module tokens table");
+       image->generic_def_objects = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_REFLECTION, "dynamic module generic definitions table");
+       image->methodspec = mono_g_hash_table_new_type ((GHashFunc)mono_object_hash, NULL, MONO_HASH_KEY_GC, MONO_ROOT_SOURCE_REFLECTION, "dynamic module method specifications table");
+       image->typespec = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal);
+       image->typeref = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal);
+       image->blob_cache = g_hash_table_new ((GHashFunc)mono_blob_entry_hash, (GCompareFunc)mono_blob_entry_equal);
+       image->gen_params = g_ptr_array_new ();
+       image->remapped_tokens = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_REFLECTION, "dynamic module remapped tokens table");
+
+       /*g_print ("string heap create for image %p (%s)\n", image, module_name);*/
+       string_heap_init (&image->sheap);
+       mono_dynstream_add_data (&image->us, "", 1);
+       mono_dynamic_image_add_to_blob_cached (image, (char*) "", 1, NULL, 0);
+       /* import tables... */
+       mono_dynstream_add_data (&image->code, (char*)entrycode, sizeof (entrycode));
+       image->iat_offset = mono_dynstream_add_zero (&image->code, 8); /* two IAT entries */
+       image->idt_offset = mono_dynstream_add_zero (&image->code, 2 * sizeof (MonoIDT)); /* two IDT entries */
+       image->imp_names_offset = mono_dynstream_add_zero (&image->code, 2); /* flags for name entry */
+       mono_dynstream_add_data (&image->code, "_CorExeMain", 12);
+       mono_dynstream_add_data (&image->code, "mscoree.dll", 12);
+       image->ilt_offset = mono_dynstream_add_zero (&image->code, 8); /* two ILT entries */
+       mono_dynstream_data_align (&image->code);
+
+       image->cli_header_offset = mono_dynstream_add_zero (&image->code, sizeof (MonoCLIHeader));
+
+       for (i=0; i < MONO_TABLE_NUM; ++i) {
+               image->tables [i].next_idx = 1;
+               image->tables [i].columns = table_sizes [i];
+       }
+
+       image->image.assembly = (MonoAssembly*)assembly;
+       image->run = assembly->run;
+       image->save = assembly->save;
+       image->pe_kind = 0x1; /* ILOnly */
+       image->machine = 0x14c; /* I386 */
+       
+       mono_profiler_module_loaded (&image->image, MONO_PROFILE_OK);
+
+       dynamic_images_lock ();
+
+       if (!dynamic_images)
+               dynamic_images = g_ptr_array_new ();
+
+       g_ptr_array_add (dynamic_images, image);
+
+       dynamic_images_unlock ();
+
+       return image;
+}
+#else /* DISABLE_REFLECTION_EMIT */
+MonoDynamicImage*
+mono_dynamic_image_create (MonoDynamicAssembly *assembly, char *assembly_name, char *module_name)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+#endif /* DISABLE_REFLECTION_EMIT */
+
+guint32
+mono_dynamic_image_add_to_blob_cached (MonoDynamicImage *assembly, char *b1, int s1, char *b2, int s2)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       guint32 idx;
+       char *copy;
+       gpointer oldkey, oldval;
+
+       copy = (char *)g_malloc (s1+s2);
+       memcpy (copy, b1, s1);
+       memcpy (copy + s1, b2, s2);
+       if (g_hash_table_lookup_extended (assembly->blob_cache, copy, &oldkey, &oldval)) {
+               g_free (copy);
+               idx = GPOINTER_TO_UINT (oldval);
+       } else {
+               idx = mono_dynstream_add_data (&assembly->blob, b1, s1);
+               mono_dynstream_add_data (&assembly->blob, b2, s2);
+               g_hash_table_insert (assembly->blob_cache, copy, GUINT_TO_POINTER (idx));
+       }
+       return idx;
+}
+
+void
+mono_dynimage_alloc_table (MonoDynamicTable *table, guint nrows)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       table->rows = nrows;
+       g_assert (table->columns);
+       if (nrows + 1 >= table->alloc_rows) {
+               while (nrows + 1 >= table->alloc_rows) {
+                       if (table->alloc_rows == 0)
+                               table->alloc_rows = 16;
+                       else
+                               table->alloc_rows *= 2;
+               }
+
+               table->values = (guint32 *)g_renew (guint32, table->values, (table->alloc_rows) * table->columns);
+       }
+}
+
+
+static void
+free_blob_cache_entry (gpointer key, gpointer val, gpointer user_data)
+{
+       g_free (key);
+}
+
+static void
+release_hashtable (MonoGHashTable **hash)
+{
+       if (*hash) {
+               mono_g_hash_table_destroy (*hash);
+               *hash = NULL;
+       }
+}
+
+void
+mono_dynamic_image_release_gc_roots (MonoDynamicImage *image)
+{
+       release_hashtable (&image->token_fixups);
+       release_hashtable (&image->handleref_managed);
+       release_hashtable (&image->tokens);
+       release_hashtable (&image->remapped_tokens);
+       release_hashtable (&image->generic_def_objects);
+       release_hashtable (&image->methodspec);
+}
+
+// Free dynamic image pass one: Free resources but not image itself
+void
+mono_dynamic_image_free (MonoDynamicImage *image)
+{
+       MonoDynamicImage *di = image;
+       GList *list;
+       int i;
+
+       if (di->methodspec)
+               mono_g_hash_table_destroy (di->methodspec);
+       if (di->typespec)
+               g_hash_table_destroy (di->typespec);
+       if (di->typeref)
+               g_hash_table_destroy (di->typeref);
+       if (di->handleref)
+               g_hash_table_destroy (di->handleref);
+       if (di->handleref_managed)
+               mono_g_hash_table_destroy (di->handleref_managed);
+       if (di->tokens)
+               mono_g_hash_table_destroy (di->tokens);
+       if (di->remapped_tokens)
+               mono_g_hash_table_destroy (di->remapped_tokens);
+       if (di->generic_def_objects)
+               mono_g_hash_table_destroy (di->generic_def_objects);
+       if (di->blob_cache) {
+               g_hash_table_foreach (di->blob_cache, free_blob_cache_entry, NULL);
+               g_hash_table_destroy (di->blob_cache);
+       }
+       if (di->standalonesig_cache)
+               g_hash_table_destroy (di->standalonesig_cache);
+       for (list = di->array_methods; list; list = list->next) {
+               ArrayMethod *am = (ArrayMethod *)list->data;
+               mono_sre_array_method_free (am);
+       }
+       g_list_free (di->array_methods);
+       if (di->gen_params) {
+               for (i = 0; i < di->gen_params->len; i++) {
+                       GenericParamTableEntry *entry = (GenericParamTableEntry *)g_ptr_array_index (di->gen_params, i);
+                       mono_sre_generic_param_table_entry_free (entry);
+               }
+               g_ptr_array_free (di->gen_params, TRUE);
+       }
+       if (di->token_fixups)
+               mono_g_hash_table_destroy (di->token_fixups);
+       if (di->method_to_table_idx)
+               g_hash_table_destroy (di->method_to_table_idx);
+       if (di->field_to_table_idx)
+               g_hash_table_destroy (di->field_to_table_idx);
+       if (di->method_aux_hash)
+               g_hash_table_destroy (di->method_aux_hash);
+       if (di->vararg_aux_hash)
+               g_hash_table_destroy (di->vararg_aux_hash);
+       g_free (di->strong_name);
+       g_free (di->win32_res);
+       if (di->public_key)
+               g_free (di->public_key);
+
+       /*g_print ("string heap destroy for image %p\n", di);*/
+       mono_dynamic_stream_reset (&di->sheap);
+       mono_dynamic_stream_reset (&di->code);
+       mono_dynamic_stream_reset (&di->resources);
+       mono_dynamic_stream_reset (&di->us);
+       mono_dynamic_stream_reset (&di->blob);
+       mono_dynamic_stream_reset (&di->tstream);
+       mono_dynamic_stream_reset (&di->guid);
+       for (i = 0; i < MONO_TABLE_NUM; ++i) {
+               g_free (di->tables [i].values);
+       }
+
+       dynamic_images_lock ();
+
+       if (dynamic_images)
+               g_ptr_array_remove (dynamic_images, di);
+
+       dynamic_images_unlock ();
+}
+
+// Free dynamic image pass two: Free image itself (might never get called in some debug modes)
+void
+mono_dynamic_image_free_image (MonoDynamicImage *image)
+{
+       /* See create_dynamic_mono_image () */
+#if HAVE_BOEHM_GC
+       /* Allocated using GC_MALLOC */
+#else
+       g_free (image);
+#endif
+}
diff --git a/mono/metadata/dynamic-stream-internals.h b/mono/metadata/dynamic-stream-internals.h
new file mode 100644 (file)
index 0000000..454f350
--- /dev/null
@@ -0,0 +1,30 @@
+/* 
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#ifndef __MONO_METADATA_DYNAMIC_STREAM_INTERNALS_H__
+#define __MONO_METADATA_DYNAMIC_STREAM_INTERNALS_H__
+
+#include <mono/metadata/object.h>
+#include <mono/metadata/metadata-internals.h>
+
+void
+mono_dynstream_init (MonoDynamicStream *stream);
+
+guint32
+mono_dynstream_insert_string (MonoDynamicStream *sh, const char *str);
+
+guint32
+mono_dynstream_insert_mstring (MonoDynamicStream *sh, MonoString *str, MonoError *error);
+
+guint32
+mono_dynstream_add_data (MonoDynamicStream *stream, const char *data, guint32 len);
+
+guint32
+mono_dynstream_add_zero (MonoDynamicStream *stream, guint32 len);
+
+void
+mono_dynstream_data_align (MonoDynamicStream *stream);
+
+#endif  /* __MONO_METADATA_DYNAMIC_STREAM_INTERNALS_H__ */
+
diff --git a/mono/metadata/dynamic-stream.c b/mono/metadata/dynamic-stream.c
new file mode 100644 (file)
index 0000000..6cf6370
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * dynamic-stream.c: MonoDynamicStream
+ * 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>
+
+#include "mono/metadata/dynamic-stream-internals.h"
+#include "mono/metadata/metadata-internals.h"
+#include "mono/utils/checked-build.h"
+#include "mono/utils/mono-error-internals.h"
+
+void
+mono_dynstream_init (MonoDynamicStream *sh)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       sh->index = 0;
+       sh->alloc_size = 4096;
+       sh->data = (char *)g_malloc (4096);
+       sh->hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+       mono_dynstream_insert_string (sh, "");
+}
+
+static void
+make_room_in_stream (MonoDynamicStream *stream, int size)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       if (size <= stream->alloc_size)
+               return;
+       
+       while (stream->alloc_size <= size) {
+               if (stream->alloc_size < 4096)
+                       stream->alloc_size = 4096;
+               else
+                       stream->alloc_size *= 2;
+       }
+       
+       stream->data = (char *)g_realloc (stream->data, stream->alloc_size);
+}
+
+guint32
+mono_dynstream_insert_string (MonoDynamicStream *sh, const char *str)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       guint32 idx;
+       guint32 len;
+       gpointer oldkey, oldval;
+
+       if (g_hash_table_lookup_extended (sh->hash, str, &oldkey, &oldval))
+               return GPOINTER_TO_UINT (oldval);
+
+       len = strlen (str) + 1;
+       idx = sh->index;
+       
+       make_room_in_stream (sh, idx + len);
+
+       /*
+        * We strdup the string even if we already copy them in sh->data
+        * so that the string pointers in the hash remain valid even if
+        * we need to realloc sh->data. We may want to avoid that later.
+        */
+       g_hash_table_insert (sh->hash, g_strdup (str), GUINT_TO_POINTER (idx));
+       memcpy (sh->data + idx, str, len);
+       sh->index += len;
+       return idx;
+}
+
+guint32
+mono_dynstream_insert_mstring (MonoDynamicStream *sh, MonoString *str, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       mono_error_init (error);
+       char *name = mono_string_to_utf8_checked (str, error);
+       return_val_if_nok (error, -1);
+       guint32 idx;
+       idx = mono_dynstream_insert_string (sh, name);
+       g_free (name);
+       return idx;
+}
+
+guint32
+mono_dynstream_add_data (MonoDynamicStream *stream, const char *data, guint32 len)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       guint32 idx;
+       
+       make_room_in_stream (stream, stream->index + len);
+       memcpy (stream->data + stream->index, data, len);
+       idx = stream->index;
+       stream->index += len;
+       /* 
+        * align index? Not without adding an additional param that controls it since
+        * we may store a blob value in pieces.
+        */
+       return idx;
+}
+
+guint32
+mono_dynstream_add_zero (MonoDynamicStream *stream, guint32 len)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       guint32 idx;
+       
+       make_room_in_stream (stream, stream->index + len);
+       memset (stream->data + stream->index, 0, len);
+       idx = stream->index;
+       stream->index += len;
+       return idx;
+}
+
+void
+mono_dynstream_data_align (MonoDynamicStream *stream)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       guint32 count = stream->index % 4;
+
+       /* we assume the stream data will be aligned */
+       if (count)
+               mono_dynstream_add_zero (stream, 4 - count);
+}
+
index 9315bdf828fed4df658bc31e68eab9fda9c95f93..1e0422e35fbc0f069b63b3136850af188a785384 100644 (file)
@@ -489,8 +489,13 @@ ves_icall_System_IO_MonoIO_FindFirst (MonoString *path,
        ifh = g_new (IncrementalFind, 1);
        ifh->find_handle = find_handle;
        ifh->utf8_path = mono_string_to_utf8_checked (path, &error);
-       if (mono_error_set_pending_exception (&error))
+       if (mono_error_set_pending_exception (&error)) {
+               MONO_ENTER_GC_SAFE;
+               FindClose (find_handle);
+               MONO_EXIT_GC_SAFE;
+               g_free (ifh);
                return NULL;
+       }
        ifh->domain = mono_domain_get ();
        *handle = ifh;
 
@@ -800,10 +805,6 @@ ves_icall_System_IO_MonoIO_Open (MonoString *filename, gint32 mode,
                if (options & FileOptions_Temporary)
                        attributes |= FILE_ATTRIBUTE_TEMPORARY;
                
-               /* Not sure if we should set FILE_FLAG_OVERLAPPED, how does this mix with the "Async" bool here? */
-               if (options & FileOptions_Asynchronous)
-                       attributes |= FILE_FLAG_OVERLAPPED;
-               
                if (options & FileOptions_WriteThrough)
                        attributes |= FILE_FLAG_WRITE_THROUGH;
        } else
index b5a19af282f4aa6e588dc7f1f28aef511acd9a7e..cd9408df98bbd073b054eeff706deb64b7a9765f 100644 (file)
@@ -145,10 +145,6 @@ void     mono_gchandle_free_domain  (MonoDomain *domain);
 
 typedef void (*FinalizerThreadCallback) (gpointer user_data);
 
-/* if there are finalizers to run, run them. Returns the number of finalizers run */
-gboolean mono_gc_pending_finalizers (void);
-void     mono_gc_finalize_notify    (void);
-
 void* mono_gc_alloc_pinned_obj (MonoVTable *vtable, size_t size);
 void* mono_gc_alloc_obj (MonoVTable *vtable, size_t size);
 void* mono_gc_alloc_vector (MonoVTable *vtable, size_t size, uintptr_t max_length);
index fab34a56b8bc34ad104d3bfba90792e804c494cb..46eaf5e224af7ad3bd1ac05a365d4415ad0d910b 100644 (file)
@@ -326,8 +326,12 @@ mono_gc_run_finalize (void *obj, void *data)
        if (log_finalizers)
                g_log ("mono-gc-finalizers", G_LOG_LEVEL_MESSAGE, "<%s at %p> Calling finalizer.", o->vtable->klass->name, o);
 
+       mono_profiler_gc_finalize_object_begin (o);
+
        runtime_invoke (o, NULL, &exc, NULL);
 
+       mono_profiler_gc_finalize_object_end (o);
+
        if (log_finalizers)
                g_log ("mono-gc-finalizers", G_LOG_LEVEL_MESSAGE, "<%s at %p> Returned from finalizer.", o->vtable->klass->name, o);
 
@@ -914,11 +918,15 @@ finalizer_thread (gpointer unused)
 
                finalize_domain_objects ();
 
+               mono_profiler_gc_finalize_begin ();
+
                /* If finished == TRUE, mono_gc_cleanup has been called (from mono_runtime_cleanup),
                 * before the domain is unloaded.
                 */
                mono_gc_invoke_finalizers ();
 
+               mono_profiler_gc_finalize_end ();
+
                mono_threads_join_threads ();
 
                reference_queue_proccess_all ();
index 56b9b9353cd706fc6bab6b125dc0112f9b6a4f92..4be4c632d10e53115c39384faec8f8aa2d0ab2e6 100644 (file)
@@ -157,9 +157,9 @@ mono_stack_mark_pop_value (MonoThreadInfo *info, HandleStackMark *stackmark, Mon
 /* Temporary place for some of the handle enabled wrapper functions*/
 
 MonoStringHandle
-mono_string_new_handle (MonoDomain *domain, const char *data)
+mono_string_new_handle (MonoDomain *domain, const char *data, MonoError *error)
 {
-       return MONO_HANDLE_NEW (MonoString, mono_string_new (domain, data));
+       return MONO_HANDLE_NEW (MonoString, mono_string_new_checked (domain, data, error));
 }
 
 MonoArrayHandle
index f5e8d29ba3088aa08a9acf3f2e4686ab5e9965db..76495a807d56109ecdb674f9158324052ee91916 100644 (file)
@@ -252,6 +252,8 @@ This is why we evaluate index and value before any call to MONO_HANDLE_RAW or ot
        } while (0)
 
 
+#define MONO_HANDLE_DOMAIN(HANDLE) (mono_object_domain (MONO_HANDLE_RAW (MONO_HANDLE_CAST (MonoObject, HANDLE))))
+
 /* Baked typed handles we all want */
 TYPED_HANDLE_DECL (MonoString);
 TYPED_HANDLE_DECL (MonoArray);
@@ -267,7 +269,7 @@ extern const MonoObjectHandle mono_null_value_handle;
 
 
 //FIXME this should go somewhere else
-MonoStringHandle mono_string_new_handle (MonoDomain *domain, const char *data);
+MonoStringHandle mono_string_new_handle (MonoDomain *domain, const char *data, MonoError *error);
 MonoArrayHandle mono_array_new_handle (MonoDomain *domain, MonoClass *eclass, uintptr_t n, MonoError *error);
 
 G_END_DECLS
index 96cb5bd78c4f9fd85c676bb9a5f413b8a422232b..7c71dc55064e6cb13c8cfc7a79dd08640f67d0bd 100644 (file)
@@ -171,7 +171,7 @@ ICALL_TYPE (COMPO_W, "System.ComponentModel.Win32Exception", COMPO_W_1)
 ICALL (COMPO_W_1, "W32ErrorMessage", ves_icall_System_ComponentModel_Win32Exception_W32ErrorMessage)
 
 ICALL_TYPE(DEFAULTC, "System.Configuration.DefaultConfig", DEFAULTC_1)
-ICALL(DEFAULTC_1, "get_bundled_machine_config", get_bundled_machine_config)
+HANDLES(ICALL(DEFAULTC_1, "get_bundled_machine_config", get_bundled_machine_config))
 ICALL(DEFAULTC_2, "get_machine_config_path", ves_icall_System_Configuration_DefaultConfig_get_machine_config_path)
 
 /* Note that the below icall shares the same function as DefaultConfig uses */
@@ -281,9 +281,9 @@ ICALL(ENV_14, "get_ProcessorCount", mono_cpu_count)
 ICALL(ENV_15, "get_TickCount", ves_icall_System_Environment_get_TickCount)
 ICALL(ENV_16, "get_UserName", ves_icall_System_Environment_get_UserName)
 ICALL(ENV_16m, "internalBroadcastSettingChange", ves_icall_System_Environment_BroadcastSettingChange)
-ICALL(ENV_17, "internalGetEnvironmentVariable", ves_icall_System_Environment_GetEnvironmentVariable)
-ICALL(ENV_18, "internalGetGacPath", ves_icall_System_Environment_GetGacPath)
-ICALL(ENV_19, "internalGetHome", ves_icall_System_Environment_InternalGetHome)
+HANDLES(ICALL(ENV_17, "internalGetEnvironmentVariable_native", ves_icall_System_Environment_GetEnvironmentVariable_native))
+HANDLES(ICALL(ENV_18, "internalGetGacPath", ves_icall_System_Environment_GetGacPath))
+HANDLES(ICALL(ENV_19, "internalGetHome", ves_icall_System_Environment_InternalGetHome))
 ICALL(ENV_20, "set_ExitCode", mono_environment_exitcode_set)
 
 ICALL_TYPE(GC, "System.GC", GC_0)
@@ -403,7 +403,7 @@ ICALL(MONOIO_32, "get_PathSeparator", ves_icall_System_IO_MonoIO_get_PathSeparat
 ICALL(MONOIO_33, "get_VolumeSeparatorChar", ves_icall_System_IO_MonoIO_get_VolumeSeparatorChar)
 
 ICALL_TYPE(IOPATH, "System.IO.Path", IOPATH_1)
-ICALL(IOPATH_1, "get_temp_path", ves_icall_System_IO_get_temp_path)
+HANDLES(ICALL(IOPATH_1, "get_temp_path", ves_icall_System_IO_get_temp_path))
 
 ICALL_TYPE(IOSELECTOR, "System.IOSelector", IOSELECTOR_1)
 ICALL(IOSELECTOR_1, "Add", ves_icall_System_IOSelector_Add)
@@ -494,7 +494,7 @@ ICALL(OBJ_2, "InternalGetHashCode", mono_object_hash)
 ICALL(OBJ_3, "MemberwiseClone", ves_icall_System_Object_MemberwiseClone)
 
 ICALL_TYPE(ASSEM, "System.Reflection.Assembly", ASSEM_1a)
-ICALL(ASSEM_1a, "GetAotId", ves_icall_System_Reflection_Assembly_GetAotId)
+HANDLES(ICALL(ASSEM_1a, "GetAotId", ves_icall_System_Reflection_Assembly_GetAotId))
 ICALL(ASSEM_2, "GetCallingAssembly", ves_icall_System_Reflection_Assembly_GetCallingAssembly)
 ICALL(ASSEM_3, "GetEntryAssembly", ves_icall_System_Reflection_Assembly_GetEntryAssembly)
 ICALL(ASSEM_4, "GetExecutingAssembly", ves_icall_System_Reflection_Assembly_GetExecutingAssembly)
@@ -509,7 +509,7 @@ ICALL(ASSEM_12, "GetReferencedAssemblies", ves_icall_System_Reflection_Assembly_
 ICALL(ASSEM_13, "GetTypes", ves_icall_System_Reflection_Assembly_GetTypes)
 ICALL(ASSEM_14, "InternalGetAssemblyName", ves_icall_System_Reflection_Assembly_InternalGetAssemblyName)
 ICALL(ASSEM_15, "InternalGetType", ves_icall_System_Reflection_Assembly_InternalGetType)
-ICALL(ASSEM_16, "InternalImageRuntimeVersion", ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion)
+HANDLES(ICALL(ASSEM_16, "InternalImageRuntimeVersion", ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion))
 ICALL(ASSEM_17, "LoadFrom", ves_icall_System_Reflection_Assembly_LoadFrom)
 ICALL(ASSEM_18, "LoadPermissions", ves_icall_System_Reflection_Assembly_LoadPermissions)
 
@@ -519,7 +519,7 @@ ICALL(ASSEM_21, "get_ReflectionOnly", ves_icall_System_Reflection_Assembly_get_R
 ICALL(ASSEM_22, "get_code_base", ves_icall_System_Reflection_Assembly_get_code_base)
 ICALL(ASSEM_23, "get_fullname", ves_icall_System_Reflection_Assembly_get_fullName)
 ICALL(ASSEM_24, "get_global_assembly_cache", ves_icall_System_Reflection_Assembly_get_global_assembly_cache)
-ICALL(ASSEM_25, "get_location", ves_icall_System_Reflection_Assembly_get_location)
+HANDLES(ICALL(ASSEM_25, "get_location", ves_icall_System_Reflection_Assembly_get_location))
 ICALL(ASSEM_26, "load_with_partial_name", ves_icall_System_Reflection_Assembly_load_with_partial_name)
 
 ICALL_TYPE(ASSEMN, "System.Reflection.AssemblyName", ASSEMN_0)
@@ -530,8 +530,7 @@ ICALL(ASSEMN_2, "get_public_token", mono_digest_get_public_token)
 ICALL_TYPE(CATTR_DATA, "System.Reflection.CustomAttributeData", CATTR_DATA_1)
 ICALL(CATTR_DATA_1, "ResolveArgumentsInternal", ves_icall_System_Reflection_CustomAttributeData_ResolveArgumentsInternal)
 
-ICALL_TYPE(ASSEMB, "System.Reflection.Emit.AssemblyBuilder", ASSEMB_1)
-ICALL(ASSEMB_1, "InternalAddModule", ves_icall_AssemblyBuilder_InternalAddModule)
+ICALL_TYPE(ASSEMB, "System.Reflection.Emit.AssemblyBuilder", ASSEMB_2)
 ICALL(ASSEMB_2, "basic_init", ves_icall_AssemblyBuilder_basic_init)
 
 #ifndef DISABLE_REFLECTION_EMIT
@@ -574,11 +573,9 @@ ICALL(SYMBOLTYPE_1, "create_unmanaged_type", ves_icall_SymbolType_create_unmanag
 
 ICALL_TYPE(TYPEB, "System.Reflection.Emit.TypeBuilder", TYPEB_1)
 ICALL(TYPEB_1, "create_generic_class", ves_icall_TypeBuilder_create_generic_class)
-ICALL(TYPEB_2, "create_internal_class", ves_icall_TypeBuilder_create_internal_class)
 ICALL(TYPEB_3, "create_runtime_class", ves_icall_TypeBuilder_create_runtime_class)
 ICALL(TYPEB_4, "get_IsGenericParameter", ves_icall_TypeBuilder_get_IsGenericParameter)
 ICALL(TYPEB_5, "get_event_info", ves_icall_TypeBuilder_get_event_info)
-ICALL(TYPEB_6, "setup_generic_class", ves_icall_TypeBuilder_setup_generic_class)
 ICALL(TYPEB_7, "setup_internal_class", ves_icall_TypeBuilder_setup_internal_class)
 
 ICALL_TYPE(EVENTI, "System.Reflection.EventInfo", EVENTI_1)
@@ -600,7 +597,7 @@ ICALL(MBASE_4, "GetMethodFromHandleInternalType_native", ves_icall_System_Reflec
 ICALL_TYPE(MODULE, "System.Reflection.Module", MODULE_1)
 ICALL(MODULE_1, "Close", ves_icall_System_Reflection_Module_Close)
 ICALL(MODULE_2, "GetGlobalType", ves_icall_System_Reflection_Module_GetGlobalType)
-ICALL(MODULE_3, "GetGuidInternal", ves_icall_System_Reflection_Module_GetGuidInternal)
+HANDLES(ICALL(MODULE_3, "GetGuidInternal", ves_icall_System_Reflection_Module_GetGuidInternal))
 ICALL(MODULE_14, "GetHINSTANCE", ves_icall_System_Reflection_Module_GetHINSTANCE)
 ICALL(MODULE_4, "GetMDStreamVersion", ves_icall_System_Reflection_Module_GetMDStreamVersion)
 ICALL(MODULE_5, "GetPEKind", ves_icall_System_Reflection_Module_GetPEKind)
@@ -798,8 +795,8 @@ ICALL(RT_18, "MakePointerType", ves_icall_RuntimeType_MakePointerType)
 HANDLES(ICALL(RT_19, "getFullName", ves_icall_System_RuntimeType_getFullName))
 ICALL(RT_21, "get_DeclaringMethod", ves_icall_RuntimeType_get_DeclaringMethod)
 ICALL(RT_22, "get_DeclaringType", ves_icall_RuntimeType_get_DeclaringType)
-ICALL(RT_23, "get_Name", ves_icall_RuntimeType_get_Name)
-ICALL(RT_24, "get_Namespace", ves_icall_RuntimeType_get_Namespace)
+HANDLES(ICALL(RT_23, "get_Name", ves_icall_RuntimeType_get_Name))
+HANDLES(ICALL(RT_24, "get_Namespace", ves_icall_RuntimeType_get_Namespace))
 ICALL(RT_25, "get_core_clr_security_level", vell_icall_RuntimeType_get_core_clr_security_level)
 ICALL(RT_26, "make_array_type", ves_icall_RuntimeType_make_array_type)
 ICALL(RT_27, "make_byref_type", ves_icall_RuntimeType_make_byref_type)
@@ -924,8 +921,8 @@ ICALL(MUTEX_3, "ReleaseMutex_internal(intptr)", ves_icall_System_Threading_Mutex
 
 ICALL_TYPE(NATIVEC, "System.Threading.NativeEventCalls", NATIVEC_1)
 ICALL(NATIVEC_1, "CloseEvent_internal", ves_icall_System_Threading_Events_CloseEvent_internal)
-ICALL(NATIVEC_2, "CreateEvent_internal(bool,bool,string,bool&)", ves_icall_System_Threading_Events_CreateEvent_internal)
-ICALL(NATIVEC_3, "OpenEvent_internal(string,System.Security.AccessControl.EventWaitHandleRights,System.IO.MonoIOError&)", ves_icall_System_Threading_Events_OpenEvent_internal)
+ICALL(NATIVEC_2, "CreateEvent_internal(bool,bool,string,int&)", ves_icall_System_Threading_Events_CreateEvent_internal)
+ICALL(NATIVEC_3, "OpenEvent_internal(string,System.Security.AccessControl.EventWaitHandleRights,int&)", ves_icall_System_Threading_Events_OpenEvent_internal)
 ICALL(NATIVEC_4, "ResetEvent_internal",  ves_icall_System_Threading_Events_ResetEvent_internal)
 ICALL(NATIVEC_5, "SetEvent_internal",    ves_icall_System_Threading_Events_SetEvent_internal)
 
index 4825e86d16512a8a17e1bd80fde8f7af93995fe6..b331969129c56a55224645737b08f9170aabb97f 100644 (file)
@@ -111,8 +111,6 @@ extern MonoString* ves_icall_System_Environment_GetOSVersionString (void);
 
 ICALL_EXPORT MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
 
-TYPED_HANDLE_DECL (MonoReflectionType);
-
 /* Lazy class loading functions */
 static GENERATE_GET_CLASS_WITH_CACHE (system_version, System, Version)
 static GENERATE_GET_CLASS_WITH_CACHE (assembly_name, System.Reflection, AssemblyName)
@@ -2638,37 +2636,38 @@ ves_icall_RuntimeType_get_DeclaringType (MonoReflectionType *type)
        return ret;
 }
 
-ICALL_EXPORT MonoString*
-ves_icall_RuntimeType_get_Name (MonoReflectionType *type)
+ICALL_EXPORT MonoStringHandle
+ves_icall_RuntimeType_get_Name (MonoReflectionTypeHandle reftype, MonoError *error)
 {
-       MonoDomain *domain = mono_domain_get (); 
-       MonoClass *klass = mono_class_from_mono_type (type->type);
+       MonoDomain *domain = mono_domain_get ();
+       MonoType *type = MONO_HANDLE_RAW(reftype)->type; 
+       MonoClass *klass = mono_class_from_mono_type (type);
 
-       if (type->type->byref) {
+       if (type->byref) {
                char *n = g_strdup_printf ("%s&", klass->name);
-               MonoString *res = mono_string_new (domain, n);
+               MonoStringHandle res = mono_string_new_handle (domain, n, error);
 
                g_free (n);
 
                return res;
        } else {
-               return mono_string_new (domain, klass->name);
+               return mono_string_new_handle (domain, klass->name, error);
        }
 }
 
-ICALL_EXPORT MonoString*
-ves_icall_RuntimeType_get_Namespace (MonoReflectionType *type)
+ICALL_EXPORT MonoStringHandle
+ves_icall_RuntimeType_get_Namespace (MonoReflectionTypeHandle type, MonoError *error)
 {
        MonoDomain *domain = mono_domain_get (); 
-       MonoClass *klass = mono_class_from_mono_type (type->type);
+       MonoClass *klass = mono_class_from_mono_type_handle (type);
 
        while (klass->nested_in)
                klass = klass->nested_in;
 
        if (klass->name_space [0] == '\0')
-               return NULL;
+               return NULL_HANDLE_STRING;
        else
-               return mono_string_new (domain, klass->name_space);
+               return mono_string_new_handle (domain, klass->name_space, error);
 }
 
 ICALL_EXPORT gint32
@@ -4542,15 +4541,12 @@ ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname,
        return result;
 }
 
-ICALL_EXPORT MonoString *
-ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly *assembly)
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssemblyHandle refassembly, MonoError *error)
 {
-       MonoDomain *domain = mono_object_domain (assembly); 
-       MonoString *res;
-
-       res = mono_string_new (domain, mono_image_get_filename (assembly->assembly->image));
-
-       return res;
+       MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
+       MonoAssembly *assembly = MONO_HANDLE_RAW (refassembly)->assembly;
+       return mono_string_new_handle (domain, mono_image_get_filename (assembly->image), error);
 }
 
 ICALL_EXPORT MonoBoolean
@@ -4559,12 +4555,13 @@ ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly
        return assembly->assembly->ref_only;
 }
 
-ICALL_EXPORT MonoString *
-ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly *assembly)
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssemblyHandle refassembly, MonoError *error)
 {
-       MonoDomain *domain = mono_object_domain (assembly); 
+       MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
+       MonoAssembly *assembly = MONO_HANDLE_RAW (refassembly)->assembly;
 
-       return mono_string_new (domain, assembly->assembly->image->version);
+       return mono_string_new_handle (domain, assembly->image->version, error);
 }
 
 ICALL_EXPORT MonoReflectionMethod*
@@ -4619,8 +4616,8 @@ ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAss
        return result;
 }
 
-ICALL_EXPORT MonoString*
-ves_icall_System_Reflection_Assembly_GetAotId ()
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_Reflection_Assembly_GetAotId (MonoError *error)
 {
        int i;
        guint8 aotid_sum = 0;
@@ -4636,8 +4633,11 @@ ves_icall_System_Reflection_Assembly_GetAotId ()
 
        if (aotid_sum == 0)
                return NULL;
-       
-       return mono_string_new (domain, mono_guid_to_string((guint8*) aotid));
+
+       gchar *guid = mono_guid_to_string((guint8*) aotid);
+       MonoStringHandle res = mono_string_new_handle (domain, guid, error);
+       g_free (guid);
+       return res;
 }
 
 static MonoObject*
@@ -5219,7 +5219,7 @@ ves_icall_System_RuntimeType_getFullName (MonoReflectionTypeHandle object, gbool
                return NULL_HANDLE_STRING;
        }
 
-       res = mono_string_new_handle (domain, name);
+       res = mono_string_new_handle (domain, name, error);
        g_free (name);
 
        return res;
@@ -5703,13 +5703,14 @@ ves_icall_System_Reflection_Module_Close (MonoReflectionModule *module)
                mono_image_close (module->image);*/
 }
 
-ICALL_EXPORT MonoString*
-ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module)
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModuleHandle refmodule, MonoError *error)
 {
-       MonoDomain *domain = mono_object_domain (module); 
+       MonoDomain *domain = MONO_HANDLE_DOMAIN (refmodule);
+       MonoImage *image = MONO_HANDLE_RAW (refmodule)->image;
 
-       g_assert (module->image);
-       return mono_string_new (domain, module->image->guid);
+       g_assert (image);
+       return mono_string_new_handle (domain, image->guid, error);
 }
 
 ICALL_EXPORT gpointer
@@ -6212,6 +6213,7 @@ ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, Mon
        MonoObject *delegate;
        gpointer func;
        MonoMethod *method = info->method;
+       MonoMethodSignature *sig = mono_method_signature(method);
 
        mono_class_init_checked (delegate_class, &error);
        if (mono_error_set_pending_exception (&error))
@@ -6236,6 +6238,13 @@ ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, Mon
                }
        }
 
+       if (sig->generic_param_count && method->wrapper_type == MONO_WRAPPER_NONE) {
+               if (!method->is_inflated) {
+                       mono_set_pending_exception(mono_get_exception_argument("method", " Cannot bind to the target method because its signature differs from that of the delegate type"));
+                       return NULL;
+               }
+       }
+
        delegate = mono_object_new_checked (mono_object_domain (type), delegate_class, &error);
        if (mono_error_set_pending_exception (&error))
                return NULL;
@@ -6541,27 +6550,20 @@ ves_icall_System_Environment_GetIs64BitOperatingSystem (void)
 #endif
 }
 
-ICALL_EXPORT MonoString *
-ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_Environment_GetEnvironmentVariable_native (const gchar *utf8_name, MonoError *error)
 {
-       MonoError error;
        const gchar *value;
-       gchar *utf8_name;
 
-       if (name == NULL)
-               return NULL;
+       if (utf8_name == NULL)
+               return NULL_HANDLE_STRING;
 
-       utf8_name = mono_string_to_utf8_checked (name, &error); /* FIXME: this should be ascii */
-       if (mono_error_set_pending_exception (&error))
-               return NULL;
        value = g_getenv (utf8_name);
 
-       g_free (utf8_name);
-
        if (value == 0)
-               return NULL;
+               return NULL_HANDLE_STRING;
        
-       return mono_string_new (mono_domain_get (), value);
+       return mono_string_new_handle (mono_domain_get (), value, error);
 }
 
 /*
@@ -6760,10 +6762,10 @@ ves_icall_System_Environment_Exit (int result)
        exit (result);
 }
 
-ICALL_EXPORT MonoString*
-ves_icall_System_Environment_GetGacPath (void)
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_Environment_GetGacPath (MonoError *error)
 {
-       return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
+       return mono_string_new_handle (mono_domain_get (), mono_assembly_getrootdir (), error);
 }
 
 ICALL_EXPORT MonoString*
@@ -6864,10 +6866,10 @@ ves_icall_System_IO_DriveInfo_GetDriveFormat (MonoString *path)
        return result;
 }
 
-ICALL_EXPORT MonoString *
-ves_icall_System_Environment_InternalGetHome (void)
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_Environment_InternalGetHome (MonoError *error)
 {
-       return mono_string_new (mono_domain_get (), g_get_home_dir ());
+       return mono_string_new_handle (mono_domain_get (), g_get_home_dir (), error);
 }
 
 static const char *encodings [] = {
@@ -7117,10 +7119,10 @@ ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClas
        }
 }
 
-ICALL_EXPORT MonoString *
-ves_icall_System_IO_get_temp_path (void)
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_IO_get_temp_path (MonoError *error)
 {
-       return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
+       return mono_string_new_handle (mono_domain_get (), g_get_tmp_dir (), error);
 }
 
 #ifndef PLATFORM_NO_DRIVEINFO
@@ -7238,17 +7240,18 @@ get_bundled_app_config (void)
        return mono_string_new (mono_domain_get (), app_config);
 }
 
-static MonoString *
-get_bundled_machine_config (void)
+/* this is an icall */
+static MonoStringHandle
+get_bundled_machine_config (MonoError *error)
 {
        const gchar *machine_config;
 
        machine_config = mono_get_machine_config ();
 
        if (!machine_config)
-               return NULL;
+               return NULL_HANDLE_STRING;
 
-       return mono_string_new (mono_domain_get (), machine_config);
+       return mono_string_new_handle (mono_domain_get (), machine_config, error);
 }
 
 ICALL_EXPORT MonoString *
@@ -8001,7 +8004,12 @@ ves_icall_Microsoft_Win32_NativeMethods_TerminateProcess (gpointer handle, gint3
 ICALL_EXPORT gint32
 ves_icall_Microsoft_Win32_NativeMethods_WaitForInputIdle (gpointer handle, gint32 milliseconds)
 {
+#ifdef HOST_WIN32
        return WaitForInputIdle (handle, milliseconds);
+#else
+       /*TODO: Not implemented*/
+       return WAIT_TIMEOUT;
+#endif
 }
 
 ICALL_EXPORT MonoBoolean
index e94b73d590cfe85fd055d00b341fc8d84198c924..6ffff1a6b7328511743975d2b247935fe7aa9d6d 100644 (file)
@@ -195,7 +195,7 @@ jit_info_table_chunk_index (MonoJitInfoTableChunk *chunk, MonoThreadHazardPointe
 
        while (left < right) {
                int pos = (left + right) / 2;
-               MonoJitInfo *ji = (MonoJitInfo *)get_hazardous_pointer((gpointer volatile*)&chunk->data [pos], hp, JIT_INFO_HAZARD_INDEX);
+               MonoJitInfo *ji = (MonoJitInfo *)mono_get_hazardous_pointer((gpointer volatile*)&chunk->data [pos], hp, JIT_INFO_HAZARD_INDEX);
                gint8 *code_end = (gint8*)ji->code_start + ji->code_size;
 
                if (addr < code_end)
@@ -228,7 +228,7 @@ jit_info_table_find (MonoJitInfoTable *table, MonoThreadHazardPointers *hp, gint
                MonoJitInfoTableChunk *chunk = table->chunks [chunk_pos];
 
                while (pos < chunk->num_elements) {
-                       ji = (MonoJitInfo *)get_hazardous_pointer ((gpointer volatile*)&chunk->data [pos], hp, JIT_INFO_HAZARD_INDEX);
+                       ji = (MonoJitInfo *)mono_get_hazardous_pointer ((gpointer volatile*)&chunk->data [pos], hp, JIT_INFO_HAZARD_INDEX);
 
                        ++pos;
 
@@ -286,7 +286,7 @@ mono_jit_info_table_find_internal (MonoDomain *domain, char *addr, gboolean try_
           table by a hazard pointer and make sure that the pointer is
           still there after we've made it hazardous, we don't have to
           worry about the writer freeing the table. */
-       table = (MonoJitInfoTable *)get_hazardous_pointer ((gpointer volatile*)&domain->jit_info_table, hp, JIT_INFO_TABLE_HAZARD_INDEX);
+       table = (MonoJitInfoTable *)mono_get_hazardous_pointer ((gpointer volatile*)&domain->jit_info_table, hp, JIT_INFO_TABLE_HAZARD_INDEX);
 
        ji = jit_info_table_find (table, hp, (gint8*)addr);
        if (hp)
@@ -298,7 +298,7 @@ mono_jit_info_table_find_internal (MonoDomain *domain, char *addr, gboolean try_
 
        /* Maybe its an AOT module */
        if (try_aot && mono_get_root_domain () && mono_get_root_domain ()->aot_modules) {
-               table = (MonoJitInfoTable *)get_hazardous_pointer ((gpointer volatile*)&mono_get_root_domain ()->aot_modules, hp, JIT_INFO_TABLE_HAZARD_INDEX);
+               table = (MonoJitInfoTable *)mono_get_hazardous_pointer ((gpointer volatile*)&mono_get_root_domain ()->aot_modules, hp, JIT_INFO_TABLE_HAZARD_INDEX);
                module_ji = jit_info_table_find (table, hp, (gint8*)addr);
                if (module_ji)
                        ji = jit_info_find_in_aot_func (domain, module_ji->d.image, addr);
index f0d2bca6ed49d12a513f5356d770a9790b2e53f3..66f7d6b560d084cac2f07ffc20249e62b699c8f9 100644 (file)
@@ -24,7 +24,6 @@
 
 #include "lock-tracer.h"
 
-
 /*
  * This is a very simple lock trace implementation. It can be used to verify that the runtime is
  * correctly following all locking rules.
@@ -141,5 +140,9 @@ mono_locks_lock_released (RuntimeLocks kind, gpointer lock)
 {
        add_record (RECORD_LOCK_RELEASED, kind, lock);
 }
-
-#endif
+#else
+       #ifdef _MSC_VER
+               // Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+               void __mono_win32_lock_tracer_quiet_lnk4221(void) {}
+       #endif
+#endif /* LOCK_TRACER */
index b27996839e9356dd40c0496abbc451ef3723a6d6..5b290e74947ff5143a963c5a2e891c4d7d71fc3f 100644 (file)
@@ -95,7 +95,7 @@ static void
 emit_struct_conv (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_object);
 
 static void
-emit_struct_conv_full (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_object, MonoMarshalNative string_encoding);
+emit_struct_conv_full (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_object, int offset_of_first_child_field, MonoMarshalNative string_encoding);
 
 static void 
 mono_struct_delete_old (MonoClass *klass, char *ptr);
@@ -1937,15 +1937,26 @@ emit_object_to_ptr_conv (MonoMethodBuilder *mb, MonoType *type, MonoMarshalConv
        }
 }
 
+static int offset_of_first_nonstatic_field(MonoClass *klass)
+{
+       int i;
+       for (i = 0; i < klass->field.count; i++) {
+               if (!(klass->fields[i].type->attrs & FIELD_ATTRIBUTE_STATIC) && !mono_field_is_deleted (&klass->fields[i]))
+                       return klass->fields[i].offset - sizeof (MonoObject);
+       }
+
+       return 0;
+}
+
 static void
 emit_struct_conv_full (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_object,
-                                          MonoMarshalNative string_encoding)
+                                               int offset_of_first_child_field, MonoMarshalNative string_encoding)
 {
        MonoMarshalType *info;
        int i;
 
        if (klass->parent)
-               emit_struct_conv(mb, klass->parent, to_object);
+               emit_struct_conv_full (mb, klass->parent, to_object, offset_of_first_nonstatic_field (klass), string_encoding);
 
        info = mono_marshal_load_type_info (klass);
 
@@ -1953,16 +1964,21 @@ emit_struct_conv_full (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_obje
                return;
 
        if (klass->blittable) {
-               int msize = mono_class_value_size (klass, NULL);
-               g_assert (msize == info->native_size);
+               int usize = mono_class_value_size (klass, NULL);
+               g_assert (usize == info->native_size);
                mono_mb_emit_ldloc (mb, 1);
                mono_mb_emit_ldloc (mb, 0);
-               mono_mb_emit_icon (mb, msize);
+               mono_mb_emit_icon (mb, usize);
                mono_mb_emit_byte (mb, CEE_PREFIX1);
                mono_mb_emit_byte (mb, CEE_CPBLK);
 
-               mono_mb_emit_add_to_local (mb, 0, msize);
-               mono_mb_emit_add_to_local (mb, 1, msize);
+               if (to_object) {
+                       mono_mb_emit_add_to_local (mb, 0, usize);
+                       mono_mb_emit_add_to_local (mb, 1, offset_of_first_child_field);
+               } else {
+                       mono_mb_emit_add_to_local (mb, 0, offset_of_first_child_field);
+                       mono_mb_emit_add_to_local (mb, 1, usize);
+               }
                return;
        }
 
@@ -2166,7 +2182,7 @@ emit_struct_conv_full (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_obje
 static void
 emit_struct_conv (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_object)
 {
-       emit_struct_conv_full (mb, klass, to_object, (MonoMarshalNative)-1);
+       emit_struct_conv_full (mb, klass, to_object, 0, (MonoMarshalNative)-1);
 }
 
 static void
@@ -3255,7 +3271,7 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt
        gboolean closed_over_null = FALSE;
        MonoGenericContext *ctx = NULL;
        MonoGenericContainer *container = NULL;
-       MonoMethod *orig_method = NULL;
+       MonoMethod *orig_method = method;
        WrapperInfo *info;
        WrapperSubtype subtype = WRAPPER_SUBTYPE_NONE;
        gboolean found;
@@ -3299,7 +3315,6 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt
         * For generic delegates, create a generic wrapper, and return an instance to help AOT.
         */
        if (method->is_inflated && subtype == WRAPPER_SUBTYPE_NONE) {
-               orig_method = method;
                ctx = &((MonoMethodInflated*)method)->context;
                method = ((MonoMethodInflated*)method)->declaring;
 
@@ -3548,7 +3563,7 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt
 #endif /* DISABLE_JIT */
 
        info = mono_wrapper_info_create (mb, subtype);
-       info->d.delegate_invoke.method = method;
+       info->d.delegate_invoke.method = orig_method;
 
        if (ctx) {
                MonoMethod *def;
@@ -6343,7 +6358,7 @@ emit_marshal_array (EmitMarshalContext *m, int argnum, MonoType *t,
                                mono_mb_emit_stloc (mb, 1);
 
                                /* emit valuetype conversion code */
-                               emit_struct_conv_full (mb, eklass, FALSE, eklass == mono_defaults.char_class ? encoding : (MonoMarshalNative)-1);
+                               emit_struct_conv_full (mb, eklass, FALSE, 0, eklass == mono_defaults.char_class ? encoding : (MonoMarshalNative)-1);
                        }
 
                        mono_mb_emit_add_to_local (mb, index_var, 1);
@@ -6488,7 +6503,7 @@ emit_marshal_array (EmitMarshalContext *m, int argnum, MonoType *t,
                                        mono_mb_emit_stloc (mb, 1);
 
                                        /* emit valuetype conversion code */
-                                       emit_struct_conv_full (mb, eklass, TRUE, eklass == mono_defaults.char_class ? encoding : (MonoMarshalNative)-1);
+                                       emit_struct_conv_full (mb, eklass, TRUE, 0, eklass == mono_defaults.char_class ? encoding : (MonoMarshalNative)-1);
                                }
 
                                if (need_free) {
@@ -10949,7 +10964,12 @@ ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalAnsi (MonoString
        if (!tres)
                return tres;
 
-       len = strlen (tres) + 1;
+       /*
+        * mono_string_to_utf8_checked() returns a memory area at least as large as the size of the
+        * MonoString, even if it contains NULL characters. The copy we allocate here has to be equally
+        * large.
+        */
+       len = MAX (strlen (tres) + 1, string->length);
        ret = ves_icall_System_Runtime_InteropServices_Marshal_AllocHGlobal (len);
        memcpy (ret, tres, len);
        g_free (tres);
index 2df6db21ec67febd81d791c9663007b2d3660c01..27115ccc9c1b1e384c9245ff8e976882159a9ed1 100644 (file)
@@ -2806,8 +2806,6 @@ static void
 free_generic_class (MonoGenericClass *gclass)
 {
        /* The gclass itself is allocated from the image set mempool */
-       if (gclass->is_dynamic)
-               mono_reflection_free_dynamic_generic_class (gclass);
        if (gclass->cached_class && gclass->cached_class->interface_id)
                mono_unload_interface_id (gclass->cached_class);
 }
@@ -2984,13 +2982,9 @@ mono_metadata_lookup_generic_class (MonoClass *container_class, MonoGenericInst
                return gclass;
        }
 
-       if (is_dynamic) {
-               MonoDynamicGenericClass *dgclass = mono_image_set_new0 (set, MonoDynamicGenericClass, 1);
-               gclass = &dgclass->generic_class;
+       gclass = mono_image_set_new0 (set, MonoGenericClass, 1);
+       if (is_dynamic)
                gclass->is_dynamic = 1;
-       } else {
-               gclass = mono_image_set_new0 (set, MonoGenericClass, 1);
-       }
 
        gclass->is_tb_open = is_tb_open;
        gclass->container_class = container_class;
@@ -6459,6 +6453,12 @@ mono_type_is_reference (MonoType *type)
                !mono_metadata_generic_class_is_valuetype (type->data.generic_class))));
 }
 
+mono_bool
+mono_type_is_generic_parameter (MonoType *type)
+{
+       return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
+}
+
 /**
  * mono_signature_get_return_type:
  * @sig: the method signature inspected
index 6a5172d8810d4b3c4e6d0400952e663f01381184..046491943d5e7d5493b9a225d2a28f7e275162c5 100644 (file)
@@ -284,7 +284,6 @@ typedef struct {
 typedef struct _MonoType MonoType;
 typedef struct _MonoGenericInst MonoGenericInst;
 typedef struct _MonoGenericClass MonoGenericClass;
-typedef struct _MonoDynamicGenericClass MonoDynamicGenericClass;
 typedef struct _MonoGenericContext MonoGenericContext;
 typedef struct _MonoGenericContainer MonoGenericContainer;
 typedef struct _MonoGenericParam MonoGenericParam;
@@ -350,6 +349,7 @@ MONO_API mono_bool mono_type_is_struct    (MonoType *type);
 MONO_API mono_bool mono_type_is_void      (MonoType *type);
 MONO_API mono_bool mono_type_is_pointer   (MonoType *type);
 MONO_API mono_bool mono_type_is_reference (MonoType *type);
+mono_bool mono_type_is_generic_parameter (MonoType *type);
 
 MONO_API MonoType*
 mono_signature_get_return_type (MonoMethodSignature *sig);
index fe09d0c24b881a1c10ee7046c94cb5c5aba395e8..ef01f3d5305c7d40fd2194627280ea832f174698 100644 (file)
@@ -930,7 +930,7 @@ retry_contended:
        if (wait_ret == MONO_SEM_TIMEDWAIT_RET_ALERTED) {
                LOCK_DEBUG (g_message ("%s: (%d) interrupted waiting, returning -1", __func__, id));
                return -1;
-       } else if (wait_ret == MONO_SEM_TIMEDWAIT_RET_ALERTED) {
+       } else if (wait_ret == MONO_SEM_TIMEDWAIT_RET_TIMEDOUT) {
                LOCK_DEBUG (g_message ("%s: (%d) timed out waiting, returning FALSE", __func__, id));
                return 0;
        } else {
index 42f36d36854a771c3b1a7c1915cbfe1cf81038dd..2bedf12cd8fa713149e7ee88a43ad09cd2912988 100644 (file)
 #endif
 #endif
 
+/**
+ * mono_config_get_os:
+ *
+ * Returns the operating system that Mono is running on, as used for dllmap entries.
+ */
+const char *
+mono_config_get_os (void)
+{
+       return CONFIG_OS;
+}
+
+/**
+ * mono_config_get_cpu:
+ *
+ * Returns the architecture that Mono is running on, as used for dllmap entries.
+ */
+const char *
+mono_config_get_cpu (void)
+{
+       return CONFIG_CPU;
+}
+
+/**
+ * mono_config_get_wordsize:
+ *
+ * Returns the word size that Mono is running on, as used for dllmap entries.
+ */
+const char *
+mono_config_get_wordsize (void)
+{
+       return CONFIG_WORDSIZE;
+}
+
 static void start_element (GMarkupParseContext *context, 
                            const gchar         *element_name,
                           const gchar        **attribute_names,
index 4e68b8a15d82762bdbc9c0be57aedfe2fd84c135..b9695c14ba296122fa8444d0c942074e2e389997 100644 (file)
 
 MONO_BEGIN_DECLS
 
+MONO_API const char *mono_config_get_os (void);
+MONO_API const char *mono_config_get_cpu (void);
+MONO_API const char *mono_config_get_wordsize (void);
+
 MONO_API const char* mono_get_config_dir (void);
 MONO_API void        mono_set_config_dir (const char *dir);
 
index e1455148696b130e5e21dffd5c0d4eaa56ad9815..c5c65b66947c8a8f83e1c8dd53f3aee795ddf1a1 100644 (file)
@@ -50,6 +50,8 @@ MONO_API int    mono_gc_get_generation  (MonoObject *object);
 MONO_API int    mono_gc_collection_count (int generation);
 MONO_API int64_t mono_gc_get_used_size   (void);
 MONO_API int64_t mono_gc_get_heap_size   (void);
+MONO_API MonoBoolean mono_gc_pending_finalizers (void);
+MONO_API void     mono_gc_finalize_notify    (void);
 MONO_API int    mono_gc_invoke_finalizers (void);
 /* heap walking is only valid in the pre-stop-world event callback */
 MONO_API int    mono_gc_walk_heap        (int flags, MonoGCReferences callback, void *data);
index dbd443d7328d4a77a92ecfb7fa22120516686886..cd2c622a89d19f0f1054157a3b8795f696415a40 100644 (file)
 #include <mach/message.h>
 #include <mach/mach_host.h>
 #include <mach/host_info.h>
+#include <sys/sysctl.h>
 #endif
-#if defined (__NetBSD__) || defined (__APPLE__)
+#if defined (__NetBSD__)
+#include <sys/param.h>
 #include <sys/sysctl.h>
+#include <sys/vmmeter.h>
 #endif
 #include "metadata/mono-perfcounters.h"
 #include "metadata/appdomain.h"
@@ -425,7 +428,7 @@ mono_determine_physical_ram_size (void)
        int mib[2] = {
                CTL_HW,
 #ifdef __NetBSD__
-               HW_PHYSMEM
+               HW_PHYSMEM64
 #else
                HW_MEMSIZE
 #endif
@@ -474,29 +477,22 @@ mono_determine_physical_ram_available_size (void)
 #elif defined (__NetBSD__)
        struct vmtotal vm_total;
        guint64 page_size;
-       int mib [2];
+       int mib[2];
        size_t len;
 
+       mib[0] = CTL_VM;
+       mib[1] = VM_METER;
 
-       mib = {
-               CTL_VM,
-#if defined (VM_METER)
-               VM_METER
-#else
-               VM_TOTAL
-#endif
-       };
        len = sizeof (vm_total);
        sysctl (mib, 2, &vm_total, &len, NULL, 0);
 
-       mib = {
-               CTL_HW,
-               HW_PAGESIZE
-       };
+       mib[0] = CTL_HW;
+       mib[1] = HW_PAGESIZE;
+
        len = sizeof (page_size);
-       sysctl (mib, 2, &page_size, &len, NULL, 0
+       sysctl (mib, 2, &page_size, &len, NULL, 0);
 
-       return ((guint64) value.t_free * page_size) / 1024;
+       return ((guint64) vm_total.t_free * page_size) / 1024;
 #elif defined (__APPLE__)
        mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
        mach_port_t host = mach_host_self();
index b27da358575742b762965b76338ececeb5248327..865b9ca1e04236ec1a7c7840436fca8c6e02de8a 100644 (file)
@@ -276,9 +276,9 @@ ves_icall_System_Security_Principal_WindowsIdentity_GetCurrentToken (void)
         */
 
        /* thread may be impersonating somebody */
-       if (OpenThreadToken (GetCurrentThread (), TOKEN_QUERY, 1, &token) == 0) {
+       if (OpenThreadToken (GetCurrentThread (), MAXIMUM_ALLOWED, 1, &token) == 0) {
                /* if not take the process identity */
-               OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &token);
+               OpenProcessToken (GetCurrentProcess (), MAXIMUM_ALLOWED, &token);
        }
 #else
        token = GINT_TO_POINTER (geteuid ());
@@ -660,9 +660,10 @@ IsMachineProtected (gunichar2 *path)
 {
        gboolean success = FALSE;
        PACL pDACL = NULL;
+       PSECURITY_DESCRIPTOR pSD = NULL;
        PSID pEveryoneSid = NULL;
 
-       DWORD dwRes = GetNamedSecurityInfoW (path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pDACL, NULL, NULL);
+       DWORD dwRes = GetNamedSecurityInfoW (path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pDACL, NULL, &pSD);
        if (dwRes != ERROR_SUCCESS)
                return FALSE;
 
@@ -679,8 +680,8 @@ IsMachineProtected (gunichar2 *path)
        /* Note: we don't need to check our own access - 
        we'll know soon enough when reading the file */
 
-       if (pDACL)
-               LocalFree (pDACL);
+       if (pSD)
+               LocalFree (pSD);
 
        return success;
 }
index c1a531c0dc87eac782c46785a481b82df532abc6..47d7dc5b1decdcde5b5cec33b24527f639ddc41d 100644 (file)
@@ -551,5 +551,9 @@ mono_gc_is_null (void)
 {
        return TRUE;
 }
-
-#endif
+#else
+       #ifdef _MSC_VER
+               // Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+               void __mono_win32_null_gc_quiet_lnk4221(void) {}
+       #endif
+#endif /* HAVE_NULL_GC */
index a3ae4dfdd377d0fe6d10a22b2d37ab35ace6bb32..06d558d60db8eaf4658ff279733a406abd67b117 100644 (file)
@@ -7,6 +7,7 @@
 #include <mono/metadata/mempool.h>
 #include <mono/metadata/class-internals.h>
 #include <mono/metadata/threads-types.h>
+#include <mono/metadata/handle.h>
 #include <mono/io-layer/io-layer.h>
 #include "mono/utils/mono-compiler.h"
 #include "mono/utils/mono-error.h"
@@ -262,6 +263,9 @@ struct _MonoReflectionType {
        MonoType  *type;
 };
 
+/* Safely access System.Type from native code */
+TYPED_HANDLE_DECL (MonoReflectionType);
+
 /* This corresponds to System.RuntimeType */
 typedef struct {
        MonoReflectionType type;
@@ -353,7 +357,6 @@ struct _MonoInternalThread {
        MonoException *abort_exc;
        int abort_state_handle;
        guint64 tid;    /* This is accessed as a gsize in the code (so it can hold a 64bit pointer on systems that need it), but needs to reserve 64 bits of space on all machines as it corresponds to a field in managed code */
-       HANDLE      start_notify;
        gpointer stack_ptr;
        gpointer *static_data;
        void *thread_info; /*This is MonoThreadInfo*, but to simplify dependencies, let's make it a void* here. */
@@ -376,14 +379,15 @@ struct _MonoInternalThread {
        gpointer interrupt_on_stop;
        gsize    flags;
        gpointer thread_pinning_ref;
+       gsize abort_protected_block_count;
        /* 
         * These fields are used to avoid having to increment corlib versions
         * when a new field is added to this structure.
         * Please synchronize any changes with InternalThread in Thread.cs, i.e. add the
         * same field there.
         */
-       gpointer unused1;
-       gpointer unused2;
+       gsize unused1;
+       gsize unused2;
 };
 
 struct _MonoThread {
@@ -584,6 +588,7 @@ typedef struct {
        void (*mono_raise_exception_with_ctx) (MonoException *ex, MonoContext *ctx);
        gboolean (*mono_exception_walk_trace) (MonoException *ex, MonoInternalExceptionFrameWalk func, gpointer user_data);
        gboolean (*mono_install_handler_block_guard) (MonoThreadUnwindState *unwind_state);
+       gboolean (*mono_current_thread_has_handle_block_guard) (void);
 } MonoRuntimeExceptionHandlingCallbacks;
 
 /* used to free a dynamic method */
@@ -808,6 +813,9 @@ struct _MonoReflectionAssembly {
        MonoString *name;
 };
 
+/* Safely access System.Reflection.Assembly from native code */
+TYPED_HANDLE_DECL (MonoReflectionAssembly);
+
 typedef struct {
        MonoReflectionType *utype;
        MonoArray *values;
@@ -1097,6 +1105,9 @@ struct _MonoReflectionModule {
        guint32 token;
 };
 
+/* Safely access System.Reflection.Module from native code */
+TYPED_HANDLE_DECL (MonoReflectionModule);
+
 typedef struct {
        MonoReflectionModule module;
        MonoDynamicImage *dynamic_image;
@@ -1329,7 +1340,6 @@ typedef struct {
 } CattrNamedArg;
 
 gboolean          mono_image_create_pefile (MonoReflectionModuleBuilder *module, HANDLE file, MonoError *error);
-MonoReflectionModule * mono_image_load_module_dynamic (MonoReflectionAssemblyBuilder *assembly, MonoString *file_name, MonoError *error);
 guint32       mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str);
 guint32       mono_image_create_token  (MonoDynamicImage *assembly, MonoObject *obj, gboolean create_methodspec, gboolean register_token, MonoError *error);
 guint32       mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types, MonoError *error);
@@ -1340,12 +1350,6 @@ void          mono_dynamic_image_release_gc_roots (MonoDynamicImage *image);
 
 void        mono_reflection_setup_internal_class  (MonoReflectionTypeBuilder *tb);
 
-void
-ves_icall_TypeBuilder_create_internal_class (MonoReflectionTypeBuilder *tb);
-
-void
-ves_icall_TypeBuilder_setup_generic_class (MonoReflectionTypeBuilder *tb);
-
 MonoReflectionType*
 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb);
 
@@ -1390,18 +1394,12 @@ mono_reflection_lookup_dynamic_token (MonoImage *image, guint32 token, gboolean
 gboolean
 mono_reflection_call_is_assignable_to (MonoClass *klass, MonoClass *oklass, MonoError *error);
 
-gboolean
-mono_reflection_is_valid_dynamic_token (MonoDynamicImage *image, guint32 token);
-
 void
 ves_icall_System_Reflection_CustomAttributeData_ResolveArgumentsInternal (MonoReflectionMethod *method, MonoReflectionAssembly *assembly, gpointer data, guint32 data_length, MonoArray **ctor_args, MonoArray ** named_args);
 
 MonoType*
 mono_reflection_type_get_handle (MonoReflectionType *ref, MonoError *error);
 
-void
-mono_reflection_free_dynamic_generic_class (MonoGenericClass *gclass);
-
 gboolean
 mono_image_build_metadata (MonoReflectionModuleBuilder *module, MonoError *error);
 
index 3f61428872f77097b9890ebc75896f26de35786d..0aede5fbb2092feb2ec7ad9c1b53ddfce4a1e903 100644 (file)
@@ -329,6 +329,7 @@ mono_runtime_class_init_full (MonoVTable *vtable, MonoError *error)
        MonoNativeThreadId tid;
        int do_initialization = 0;
        MonoDomain *last_domain = NULL;
+       MonoException * pending_tae = NULL;
 
        mono_error_init (error);
 
@@ -431,14 +432,22 @@ mono_runtime_class_init_full (MonoVTable *vtable, MonoError *error)
 
        if (do_initialization) {
                MonoException *exc = NULL;
+
+               mono_threads_begin_abort_protected_block ();
                mono_runtime_try_invoke (method, NULL, NULL, (MonoObject**) &exc, error);
-               if (exc != NULL && mono_error_ok (error)) {
-                       mono_error_set_exception_instance (error, exc);
-               }
+               mono_threads_end_abort_protected_block ();
+
+               //exception extracted, error will be set to the right value later
+               if (exc == NULL && !mono_error_ok (error))//invoking failed but exc was not set
+                       exc = mono_error_convert_to_exception (error);
+               else
+                       mono_error_cleanup (error);
+
+               mono_error_init (error);
 
                /* If the initialization failed, mark the class as unusable. */
                /* Avoid infinite loops */
-               if (!(mono_error_ok(error) ||
+               if (!(!exc ||
                          (klass->image == mono_defaults.corlib &&
                           !strcmp (klass->name_space, "System") &&
                           !strcmp (klass->name, "TypeInitializationException")))) {
@@ -451,15 +460,9 @@ mono_runtime_class_init_full (MonoVTable *vtable, MonoError *error)
 
                        MonoException *exc_to_throw = mono_get_exception_type_initialization_checked (full_name, exc, error);
                        g_free (full_name);
-                       return_val_if_nok (error, FALSE);
 
-                       mono_error_set_exception_instance (error, exc_to_throw);
+                       mono_error_assert_ok (error); //We can't recover from this, no way to fail a type we can't alloc a failure.
 
-                       MonoException *exc_to_store = mono_error_convert_to_exception (error);
-                       /* What we really want to do here is clone the error object and store one copy in the
-                        * domain's exception hash and use the other one to error out here. */
-                       mono_error_init (error);
-                       mono_error_set_exception_instance (error, exc_to_store);
                        /*
                         * Store the exception object so it could be thrown on subsequent
                         * accesses.
@@ -467,7 +470,7 @@ mono_runtime_class_init_full (MonoVTable *vtable, MonoError *error)
                        mono_domain_lock (domain);
                        if (!domain->type_init_exception_hash)
                                domain->type_init_exception_hash = mono_g_hash_table_new_type (mono_aligned_addr_hash, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "type initialization exceptions table");
-                       mono_g_hash_table_insert (domain->type_init_exception_hash, klass, exc_to_store);
+                       mono_g_hash_table_insert (domain->type_init_exception_hash, klass, exc_to_throw);
                        mono_domain_unlock (domain);
                }
 
@@ -475,6 +478,11 @@ mono_runtime_class_init_full (MonoVTable *vtable, MonoError *error)
                        mono_domain_set (last_domain, TRUE);
                lock->done = TRUE;
                mono_type_init_unlock (lock);
+               if (exc && mono_object_class (exc) == mono_defaults.threadabortexception_class)
+                       pending_tae = exc;
+               //TAEs are blocked around .cctors, they must escape as soon as no cctor is left to run.
+               if (!pending_tae)
+                       pending_tae = mono_thread_try_resume_interruption ();
        } else {
                /* this just blocks until the initializing thread is done */
                mono_type_init_lock (lock);
@@ -495,7 +503,10 @@ mono_runtime_class_init_full (MonoVTable *vtable, MonoError *error)
                vtable->initialized = 1;
        mono_type_initialization_unlock ();
 
-       if (vtable->init_failed) {
+       //TAE wins over TIE
+       if (pending_tae)
+               mono_error_set_exception_instance (error, pending_tae);
+       else if (vtable->init_failed) {
                /* Either we were the initializing thread or we waited for the initialization */
                mono_error_set_exception_instance (error, get_type_init_exception_for_vtable (vtable));
                return FALSE;
@@ -4660,10 +4671,13 @@ mono_unhandled_exception (MonoObject *exc)
        if (!current_appdomain_delegate && !root_appdomain_delegate) {
                mono_print_unhandled_exception (exc);
        } else {
+               /* unhandled exception callbacks must not be aborted */
+               mono_threads_begin_abort_protected_block ();
                if (root_appdomain_delegate)
                        call_unhandled_exception_delegate (root_domain, root_appdomain_delegate, exc);
                if (current_appdomain_delegate)
                        call_unhandled_exception_delegate (current_domain, current_appdomain_delegate, exc);
+               mono_threads_end_abort_protected_block ();
        }
 
        /* set exitcode only if we will abort the process */
@@ -7533,14 +7547,16 @@ ves_icall_System_Runtime_Remoting_Messaging_AsyncResult_Invoke (MonoAsyncResult
 
                ac->msg->exc = NULL;
 
-               MonoError invoke_error;
-               res = mono_message_invoke (ares->async_delegate, ac->msg, &ac->msg->exc, &ac->out_args, &invoke_error);
+               res = mono_message_invoke (ares->async_delegate, ac->msg, &ac->msg->exc, &ac->out_args, &error);
+
+               /* The exit side of the invoke must not be aborted as it would leave the runtime in an undefined state */
+               mono_threads_begin_abort_protected_block ();
 
                if (!ac->msg->exc) {
-                       MonoException *ex = mono_error_convert_to_exception (&invoke_error);
+                       MonoException *ex = mono_error_convert_to_exception (&error);
                        ac->msg->exc = (MonoObject *)ex;
                } else {
-                       mono_error_cleanup (&invoke_error);
+                       mono_error_cleanup (&error);
                }
 
                MONO_OBJECT_SETREF (ac, res, res);
@@ -7554,11 +7570,14 @@ ves_icall_System_Runtime_Remoting_Messaging_AsyncResult_Invoke (MonoAsyncResult
                if (wait_event != NULL)
                        SetEvent (wait_event);
 
-               if (ac->cb_method) {
+               mono_error_init (&error); //the else branch would leave it in an undefined state
+               if (ac->cb_method)
                        mono_runtime_invoke_checked (ac->cb_method, ac->cb_target, (gpointer*) &ares, &error);
-                       if (mono_error_set_pending_exception (&error))
-                               return NULL;
-               }
+
+               mono_threads_end_abort_protected_block ();
+
+               if (mono_error_set_pending_exception (&error))
+                       return NULL;
        }
 
        return res;
index 5888b90fca925bdcfd35082990fa52a0fa83fb4d..1bf80e2c867a41e775e7b2ebb3ba1da5794d2f5f 100644 (file)
@@ -75,6 +75,11 @@ void mono_profiler_gc_moves       (void **objects, int num);
 void mono_profiler_gc_handle      (int op, int type, uintptr_t handle, MonoObject *obj);
 void mono_profiler_gc_roots       (int num, void **objects, int *root_types, uintptr_t *extra_info);
 
+void mono_profiler_gc_finalize_begin (void);
+void mono_profiler_gc_finalize_object_begin (MonoObject *obj);
+void mono_profiler_gc_finalize_object_end (MonoObject *obj);
+void mono_profiler_gc_finalize_end (void);
+
 void mono_profiler_code_chunk_new (gpointer chunk, int size);
 void mono_profiler_code_chunk_destroy (gpointer chunk);
 void mono_profiler_code_buffer_new (gpointer buffer, int size, MonoProfilerCodeBufferType type, gconstpointer data);
index 4920694b731f928265424c78bfa730b5238bd7aa..fb4cdeca08b8632bf1f746c8ea5bda5b26a1517a 100644 (file)
@@ -102,6 +102,11 @@ struct _ProfilerDesc {
        MonoProfileGCHandleFunc  gc_handle;
        MonoProfileGCRootFunc    gc_roots;
 
+       MonoProfileGCFinalizeFunc gc_finalize_begin;
+       MonoProfileGCFinalizeObjectFunc gc_finalize_object_begin;
+       MonoProfileGCFinalizeObjectFunc gc_finalize_object_end;
+       MonoProfileGCFinalizeFunc gc_finalize_end;
+
        MonoProfileFunc          runtime_initialized_event;
 
        MonoProfilerCodeChunkNew code_chunk_new;
@@ -925,6 +930,50 @@ mono_profiler_install_gc_roots (MonoProfileGCHandleFunc handle_callback, MonoPro
        prof_list->gc_roots = roots_callback;
 }
 
+void
+mono_profiler_gc_finalize_begin (void)
+{
+       for (ProfilerDesc *prof = prof_list; prof; prof = prof->next)
+               if ((prof->events & MONO_PROFILE_GC_FINALIZATION) && prof->gc_finalize_begin)
+                       prof->gc_finalize_begin (prof->profiler);
+}
+
+void
+mono_profiler_gc_finalize_object_begin (MonoObject *obj)
+{
+       for (ProfilerDesc *prof = prof_list; prof; prof = prof->next)
+               if ((prof->events & MONO_PROFILE_GC_FINALIZATION) && prof->gc_finalize_object_begin)
+                       prof->gc_finalize_object_begin (prof->profiler, obj);
+}
+
+void
+mono_profiler_gc_finalize_object_end (MonoObject *obj)
+{
+       for (ProfilerDesc *prof = prof_list; prof; prof = prof->next)
+               if ((prof->events & MONO_PROFILE_GC_FINALIZATION) && prof->gc_finalize_object_end)
+                       prof->gc_finalize_object_end (prof->profiler, obj);
+}
+
+void
+mono_profiler_gc_finalize_end (void)
+{
+       for (ProfilerDesc *prof = prof_list; prof; prof = prof->next)
+               if ((prof->events & MONO_PROFILE_GC_FINALIZATION) && prof->gc_finalize_end)
+                       prof->gc_finalize_end (prof->profiler);
+}
+
+void
+mono_profiler_install_gc_finalize (MonoProfileGCFinalizeFunc begin, MonoProfileGCFinalizeObjectFunc begin_obj, MonoProfileGCFinalizeObjectFunc end_obj, MonoProfileGCFinalizeFunc end)
+{
+       if (!prof_list)
+               return;
+
+       prof_list->gc_finalize_begin = begin;
+       prof_list->gc_finalize_object_begin = begin_obj;
+       prof_list->gc_finalize_object_begin = end_obj;
+       prof_list->gc_finalize_end = end;
+}
+
 void
 mono_profiler_install_runtime_initialized (MonoProfileFunc runtime_initialized_callback)
 {
index b793548ef8fbd98782f7975b1b08ffd0d0a3634d..84dc1bb83b1bca0dbdf7309649757483a5fbe593 100644 (file)
@@ -31,7 +31,8 @@ typedef enum {
        MONO_PROFILE_IOMAP_EVENTS     = 1 << 18, /* this should likely be removed, too */
        MONO_PROFILE_GC_MOVES         = 1 << 19,
        MONO_PROFILE_GC_ROOTS         = 1 << 20,
-       MONO_PROFILE_CONTEXT_EVENTS   = 1 << 21
+       MONO_PROFILE_CONTEXT_EVENTS   = 1 << 21,
+       MONO_PROFILE_GC_FINALIZATION  = 1 << 22
 } MonoProfileFlags;
 
 typedef enum {
@@ -39,6 +40,7 @@ typedef enum {
        MONO_PROFILE_FAILED
 } MonoProfileResult;
 
+// Keep somewhat in sync with libgc/include/gc.h:enum GC_EventType
 typedef enum {
        MONO_GC_EVENT_START,
        MONO_GC_EVENT_MARK_START,
@@ -46,10 +48,26 @@ typedef enum {
        MONO_GC_EVENT_RECLAIM_START,
        MONO_GC_EVENT_RECLAIM_END,
        MONO_GC_EVENT_END,
+       /*
+        * This is the actual arrival order of the following events:
+        *
+        * MONO_GC_EVENT_PRE_STOP_WORLD
+        * MONO_GC_EVENT_PRE_STOP_WORLD_LOCKED
+        * MONO_GC_EVENT_POST_STOP_WORLD
+        * MONO_GC_EVENT_PRE_START_WORLD
+        * MONO_GC_EVENT_POST_START_WORLD_UNLOCKED
+        * MONO_GC_EVENT_POST_START_WORLD
+        *
+        * The LOCKED and UNLOCKED events guarantee that, by the time they arrive,
+        * the GC and suspend locks will both have been acquired and released,
+        * respectively.
+        */
        MONO_GC_EVENT_PRE_STOP_WORLD,
        MONO_GC_EVENT_POST_STOP_WORLD,
        MONO_GC_EVENT_PRE_START_WORLD,
-       MONO_GC_EVENT_POST_START_WORLD
+       MONO_GC_EVENT_POST_START_WORLD,
+       MONO_GC_EVENT_PRE_STOP_WORLD_LOCKED,
+       MONO_GC_EVENT_POST_START_WORLD_UNLOCKED
 } MonoGCEvent;
 
 /* coverage info */
@@ -150,6 +168,9 @@ typedef void (*MonoProfileGCResizeFunc)   (MonoProfiler *prof, int64_t new_size)
 typedef void (*MonoProfileGCHandleFunc)   (MonoProfiler *prof, int op, int type, uintptr_t handle, MonoObject *obj);
 typedef void (*MonoProfileGCRootFunc)     (MonoProfiler *prof, int num_roots, void **objects, int *root_types, uintptr_t *extra_info);
 
+typedef void (*MonoProfileGCFinalizeFunc)  (MonoProfiler *prof);
+typedef void (*MonoProfileGCFinalizeObjectFunc) (MonoProfiler *prof, MonoObject *obj);
+
 typedef void (*MonoProfileIomapFunc) (MonoProfiler *prof, const char *report, const char *pathname, const char *new_pathname);
 
 typedef mono_bool (*MonoProfileCoverageFilterFunc)   (MonoProfiler *prof, MonoMethod *method);
@@ -197,6 +218,7 @@ MONO_API void mono_profiler_coverage_get  (MonoProfiler *prof, MonoMethod *metho
 MONO_API void mono_profiler_install_gc    (MonoProfileGCFunc callback, MonoProfileGCResizeFunc heap_resize_callback);
 MONO_API void mono_profiler_install_gc_moves    (MonoProfileGCMoveFunc callback);
 MONO_API void mono_profiler_install_gc_roots    (MonoProfileGCHandleFunc handle_callback, MonoProfileGCRootFunc roots_callback);
+MONO_API void mono_profiler_install_gc_finalize (MonoProfileGCFinalizeFunc begin, MonoProfileGCFinalizeObjectFunc begin_obj, MonoProfileGCFinalizeObjectFunc end_obj, MonoProfileGCFinalizeFunc end);
 MONO_API void mono_profiler_install_runtime_initialized (MonoProfileFunc runtime_initialized_callback);
 
 MONO_API void mono_profiler_install_code_chunk_new (MonoProfilerCodeChunkNew callback);
diff --git a/mono/metadata/reflection-cache.h b/mono/metadata/reflection-cache.h
new file mode 100644 (file)
index 0000000..ec4d722
--- /dev/null
@@ -0,0 +1,80 @@
+/* 
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#ifndef __MONO_METADATA_REFLECTION_CACHE_H__
+#define __MONO_METADATA_REFLECTION_CACHE_H__
+
+#include <glib.h>
+#include <mono/metadata/domain-internals.h>
+#include <mono/metadata/mono-hash.h>
+#include <mono/metadata/mempool.h>
+
+/*
+ * We need to return always the same object for MethodInfo, FieldInfo etc..
+ * but we need to consider the reflected type.
+ * type uses a different hash, since it uses custom hash/equal functions.
+ */
+
+typedef struct {
+       gpointer item;
+       MonoClass *refclass;
+} ReflectedEntry;
+
+gboolean
+reflected_equal (gconstpointer a, gconstpointer b);
+
+guint
+reflected_hash (gconstpointer a);
+
+#ifdef HAVE_BOEHM_GC
+/* ReflectedEntry doesn't need to be GC tracked */
+#define ALLOC_REFENTRY g_new0 (ReflectedEntry, 1)
+#define FREE_REFENTRY(entry) g_free ((entry))
+#define REFENTRY_REQUIRES_CLEANUP
+#else
+#define ALLOC_REFENTRY (ReflectedEntry *)mono_mempool_alloc (domain->mp, sizeof (ReflectedEntry))
+/* FIXME: */
+#define FREE_REFENTRY(entry)
+#endif
+
+
+#define CACHE_OBJECT(t,p,o,k)  \
+       do {    \
+               t _obj; \
+        ReflectedEntry pe; \
+        pe.item = (p); \
+        pe.refclass = (k); \
+        mono_domain_lock (domain); \
+               if (!domain->refobject_hash)    \
+                       domain->refobject_hash = mono_g_hash_table_new_type (reflected_hash, reflected_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection objects table");  \
+        _obj = (t)mono_g_hash_table_lookup (domain->refobject_hash, &pe); \
+        if (!_obj) { \
+                   ReflectedEntry *e = ALLOC_REFENTRY;         \
+                   e->item = (p);      \
+                   e->refclass = (k);  \
+                   mono_g_hash_table_insert (domain->refobject_hash, e,o);     \
+            _obj = o; \
+        } \
+               mono_domain_unlock (domain);    \
+        return _obj; \
+       } while (0)
+
+#define CHECK_OBJECT(t,p,k)    \
+       do {    \
+               t _obj; \
+               ReflectedEntry e;       \
+               e.item = (p);   \
+               e.refclass = (k);       \
+               mono_domain_lock (domain);      \
+               if (!domain->refobject_hash)    \
+                       domain->refobject_hash = mono_g_hash_table_new_type (reflected_hash, reflected_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection objects table");  \
+               if ((_obj = (t)mono_g_hash_table_lookup (domain->refobject_hash, &e))) {        \
+                       mono_domain_unlock (domain);    \
+                       return _obj;    \
+               }       \
+        mono_domain_unlock (domain); \
+       } while (0)
+
+
+#endif /*__MONO_METADATA_REFLECTION_CACHE_H__*/
index 327bb93142ce85d0579bf1bd8ae484a92e545331..967867149caa4c79eaea873cd615b16ee230bd95 100644 (file)
@@ -1,14 +1,23 @@
 /* 
  * Copyright 2014 Xamarin Inc
+ * Copyright 2016 Microsoft
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 #ifndef __MONO_METADATA_REFLECTION_INTERNALS_H__
 #define __MONO_METADATA_REFLECTION_INTERNALS_H__
 
+#include <mono/metadata/object-internals.h>
 #include <mono/metadata/reflection.h>
+#include <mono/metadata/class-internals.h>
 #include <mono/utils/mono-compiler.h>
 #include <mono/utils/mono-error.h>
 
+gboolean
+mono_reflection_is_usertype (MonoReflectionType *ref);
+
+MonoReflectionType*
+mono_reflection_type_resolve_user_types (MonoReflectionType *type, MonoError *error);
+
 MonoType*
 mono_reflection_get_type_checked (MonoImage *rootimage, MonoImage* image, MonoTypeNameParse *info, mono_bool ignorecase, mono_bool *type_resolve, MonoError *error);
 
@@ -82,5 +91,8 @@ mono_module_file_get_object_checked (MonoDomain *domain, MonoImage *image, int t
 MonoReflectionMethodBody*
 mono_method_body_get_object_checked (MonoDomain *domain, MonoMethod *method, MonoError *error);
 
+MonoClass *
+mono_class_from_mono_type_handle (MonoReflectionTypeHandle h);
+
 
 #endif /* __MONO_METADATA_REFLECTION_INTERNALS_H__ */
index 3754f2a5ba5fd3b48a2ffb4c0ec930761af0df6b..0a5ea615a03f73a95bfc4822f98dd4307a265158 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * reflection.c: Routines for creating an image at runtime.
+ * reflection.c: System.Type icalls and related reflection queries.
  * 
  * Author:
  *   Paolo Molaro (lupus@ximian.com)
@@ -7,11 +7,11 @@
  * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
  * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
  * Copyright 2011 Rodrigo Kumpera
+ * Copyright 2016 Microsoft
  *
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 #include <config.h>
-#include "mono/utils/mono-digest.h"
 #include "mono/utils/mono-membar.h"
 #include "mono/metadata/reflection-internals.h"
 #include "mono/metadata/tabledefs.h"
@@ -19,7 +19,6 @@
 #include <mono/metadata/profiler-private.h>
 #include "mono/metadata/class-internals.h"
 #include "mono/metadata/gc-internals.h"
-#include "mono/metadata/tokentype.h"
 #include "mono/metadata/domain-internals.h"
 #include "mono/metadata/opcodes.h"
 #include "mono/metadata/assembly.h"
@@ -27,6 +26,8 @@
 #include <mono/metadata/exception.h>
 #include <mono/metadata/marshal.h>
 #include <mono/metadata/security-manager.h>
+#include <mono/metadata/reflection-cache.h>
+#include <mono/metadata/sre-internals.h>
 #include <stdio.h>
 #include <glib.h>
 #include <errno.h>
 #include <mono/utils/mono-error-internals.h>
 #include <mono/utils/checked-build.h>
 
-static gboolean is_usertype (MonoReflectionType *ref);
-static MonoReflectionType *mono_reflection_type_resolve_user_types (MonoReflectionType *type, MonoError *error);
-static gboolean mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error);
-static void mono_image_module_basic_init (MonoReflectionModuleBuilder *module);
-
-typedef struct {
-       char *p;
-       char *buf;
-       char *end;
-} SigBuffer;
-
-#define TEXT_OFFSET 512
-#define CLI_H_SIZE 136
-#define FILE_ALIGN 512
-#define VIRT_ALIGN 8192
-#define START_TEXT_RVA  0x00002000
-
-typedef struct {
-       MonoReflectionILGen *ilgen;
-       MonoReflectionType *rtype;
-       MonoArray *parameters;
-       MonoArray *generic_params;
-       MonoGenericContainer *generic_container;
-       MonoArray *pinfo;
-       MonoArray *opt_types;
-       guint32 attrs;
-       guint32 iattrs;
-       guint32 call_conv;
-       guint32 *table_idx; /* note: it's a pointer */
-       MonoArray *code;
-       MonoObject *type;
-       MonoString *name;
-       MonoBoolean init_locals;
-       MonoBoolean skip_visibility;
-       MonoArray *return_modreq;
-       MonoArray *return_modopt;
-       MonoArray *param_modreq;
-       MonoArray *param_modopt;
-       MonoArray *permissions;
-       MonoMethod *mhandle;
-       guint32 nrefs;
-       gpointer *refs;
-       /* for PInvoke */
-       int charset, extra_flags, native_cc;
-       MonoString *dll, *dllentry;
-} ReflectionMethodBuilder;
-
-typedef struct {
-       guint32 owner;
-       MonoReflectionGenericParam *gparam;
-} GenericParamTableEntry;
-
-const unsigned char table_sizes [MONO_TABLE_NUM] = {
-       MONO_MODULE_SIZE,
-       MONO_TYPEREF_SIZE,
-       MONO_TYPEDEF_SIZE,
-       0,
-       MONO_FIELD_SIZE,
-       0,
-       MONO_METHOD_SIZE,
-       0,
-       MONO_PARAM_SIZE,
-       MONO_INTERFACEIMPL_SIZE,
-       MONO_MEMBERREF_SIZE,    /* 0x0A */
-       MONO_CONSTANT_SIZE,
-       MONO_CUSTOM_ATTR_SIZE,
-       MONO_FIELD_MARSHAL_SIZE,
-       MONO_DECL_SECURITY_SIZE,
-       MONO_CLASS_LAYOUT_SIZE,
-       MONO_FIELD_LAYOUT_SIZE, /* 0x10 */
-       MONO_STAND_ALONE_SIGNATURE_SIZE,
-       MONO_EVENT_MAP_SIZE,
-       0,
-       MONO_EVENT_SIZE,
-       MONO_PROPERTY_MAP_SIZE,
-       0,
-       MONO_PROPERTY_SIZE,
-       MONO_METHOD_SEMA_SIZE,
-       MONO_METHODIMPL_SIZE,
-       MONO_MODULEREF_SIZE,    /* 0x1A */
-       MONO_TYPESPEC_SIZE,
-       MONO_IMPLMAP_SIZE,      
-       MONO_FIELD_RVA_SIZE,
-       0,
-       0,
-       MONO_ASSEMBLY_SIZE,     /* 0x20 */
-       MONO_ASSEMBLY_PROCESSOR_SIZE,
-       MONO_ASSEMBLYOS_SIZE,
-       MONO_ASSEMBLYREF_SIZE,
-       MONO_ASSEMBLYREFPROC_SIZE,
-       MONO_ASSEMBLYREFOS_SIZE,
-       MONO_FILE_SIZE,
-       MONO_EXP_TYPE_SIZE,
-       MONO_MANIFEST_SIZE,
-       MONO_NESTED_CLASS_SIZE,
-
-       MONO_GENERICPARAM_SIZE, /* 0x2A */
-       MONO_METHODSPEC_SIZE,
-       MONO_GENPARCONSTRAINT_SIZE
-
-};
-
-#ifndef DISABLE_REFLECTION_EMIT
-static guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec);
-static guint32 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_open_instance, MonoError *error);
-static guint32 mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtorBuilder *cb, MonoError *error);
-static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error);
-static gboolean ensure_runtime_vtable (MonoClass *klass, MonoError  *error);
-static gpointer resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context, MonoError *error);
-static guint32 mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method, MonoError *error);
-static guint32 encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericContext *context);
-static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
-static gboolean reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error);
-static gboolean reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error);
-static guint32 create_generic_typespec (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *tb, MonoError *error);
-#endif
-
-static guint32 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type);
-static guint32 mono_image_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType *type, gboolean try_typespec);
-static void    mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly);
-static guint32 encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo, MonoError *error);
-static guint32 encode_constant (MonoDynamicImage *assembly, MonoObject *val, guint32 *ret_type);
-static char*   type_get_qualified_name (MonoType *type, MonoAssembly *ass);
-static void    encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf);
 static void get_default_param_value_blobs (MonoMethod *method, char **blobs, guint32 *types);
-static MonoReflectionType *mono_reflection_type_get_underlying_system_type (MonoReflectionType* t, MonoError *error);
 static MonoType* mono_reflection_get_type_with_rootimage (MonoImage *rootimage, MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve, MonoError *error);
-static MonoReflectionType* mono_reflection_type_resolve_user_types (MonoReflectionType *type, MonoError *error);
-static gboolean is_sre_array (MonoClass *klass);
-static gboolean is_sre_byref (MonoClass *klass);
-static gboolean is_sre_pointer (MonoClass *klass);
-static gboolean is_sre_type_builder (MonoClass *klass);
-static gboolean is_sre_method_builder (MonoClass *klass);
-static gboolean is_sre_ctor_builder (MonoClass *klass);
-static gboolean is_sre_field_builder (MonoClass *klass);
-static gboolean is_sr_mono_method (MonoClass *klass);
-static gboolean is_sr_mono_cmethod (MonoClass *klass);
-static gboolean is_sr_mono_generic_method (MonoClass *klass);
-static gboolean is_sr_mono_generic_cmethod (MonoClass *klass);
-static gboolean is_sr_mono_field (MonoClass *klass);
-static gboolean is_sr_mono_property (MonoClass *klass);
-static gboolean is_sre_method_on_tb_inst (MonoClass *klass);
-static gboolean is_sre_ctor_on_tb_inst (MonoClass *klass);
-
-static gboolean type_is_reference (MonoType *type);
-
-static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method);
-static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m);
-static MonoMethod * inflate_method (MonoReflectionType *type, MonoObject *obj, MonoError *error);
-
-static guint32 create_typespec (MonoDynamicImage *assembly, MonoType *type);
-static void init_type_builder_generics (MonoObject *type, MonoError *error);
-
-#define RESOLVE_TYPE(type, error) do {                                 \
-       type = (MonoObject *)mono_reflection_type_resolve_user_types ((MonoReflectionType*)type, error); \
-} while (0)
-#define RESOLVE_ARRAY_TYPE_ELEMENT(array, index, error) do {           \
-       MonoReflectionType *__type = mono_array_get (array, MonoReflectionType*, index); \
-       __type = mono_reflection_type_resolve_user_types (__type, error); \
-       if (mono_error_ok (error))                                      \
-               mono_array_set (arr, MonoReflectionType*, index, __type); \
-} while (0)
-
-#define mono_type_array_get_and_resolve(array, index, error) mono_reflection_type_get_handle ((MonoReflectionType*)mono_array_get (array, gpointer, index), error)
-
-#define CHECK_ADD4_OVERFLOW_UN(a, b) ((guint32)(0xFFFFFFFFU) - (guint32)(b) < (guint32)(a))
-#define CHECK_ADD8_OVERFLOW_UN(a, b) ((guint64)(0xFFFFFFFFFFFFFFFFUL) - (guint64)(b) < (guint64)(a))
-
-#if SIZEOF_VOID_P == 4
-#define CHECK_ADDP_OVERFLOW_UN(a,b) CHECK_ADD4_OVERFLOW_UN(a, b)
-#else
-#define CHECK_ADDP_OVERFLOW_UN(a,b) CHECK_ADD8_OVERFLOW_UN(a, b)
-#endif
-
-#define ADDP_IS_GREATER_OR_OVF(a, b, c) (((a) + (b) > (c)) || CHECK_ADDP_OVERFLOW_UN (a, b))
-#define ADD_IS_GREATER_OR_OVF(a, b, c) (((a) + (b) > (c)) || CHECK_ADD4_OVERFLOW_UN (a, b))
 
 /* Class lazy loading functions */
 static GENERATE_GET_CLASS_WITH_CACHE (mono_assembly, System.Reflection, MonoAssembly)
@@ -238,14222 +65,2313 @@ static GENERATE_GET_CLASS_WITH_CACHE (missing, System.Reflection, Missing);
 static GENERATE_GET_CLASS_WITH_CACHE (method_body, System.Reflection, MethodBody);
 static GENERATE_GET_CLASS_WITH_CACHE (local_variable_info, System.Reflection, LocalVariableInfo);
 static GENERATE_GET_CLASS_WITH_CACHE (exception_handling_clause, System.Reflection, ExceptionHandlingClause);
-static GENERATE_GET_CLASS_WITH_CACHE (custom_attribute_typed_argument, System.Reflection, CustomAttributeTypedArgument);
-static GENERATE_GET_CLASS_WITH_CACHE (custom_attribute_named_argument, System.Reflection, CustomAttributeNamedArgument);
 static GENERATE_GET_CLASS_WITH_CACHE (type_builder, System.Reflection.Emit, TypeBuilder);
-static GENERATE_GET_CLASS_WITH_CACHE (marshal_as_attribute, System.Runtime.InteropServices, MarshalAsAttribute);
 static GENERATE_GET_CLASS_WITH_CACHE (dbnull, System, DBNull);
 
-// The dynamic images list is only needed to support the mempool reference tracking feature in checked-build.
-static GPtrArray *dynamic_images;
-static mono_mutex_t dynamic_images_mutex;
-
-static inline void
-dynamic_images_lock (void)
-{
-       mono_os_mutex_lock (&dynamic_images_mutex);
-}
-
-static inline void
-dynamic_images_unlock (void)
-{
-       mono_os_mutex_unlock (&dynamic_images_mutex);
-}
-
-/**
- * mono_find_dynamic_image_owner:
- *
- * Find the dynamic image, if any, which a given pointer is located in the memory of.
- */
-MonoImage *
-mono_find_dynamic_image_owner (void *ptr)
-{
-       MonoImage *owner = NULL;
-       int i;
-
-       dynamic_images_lock ();
-
-       if (dynamic_images)
-       {
-               for (i = 0; !owner && i < dynamic_images->len; ++i) {
-                       MonoImage *image = (MonoImage *)g_ptr_array_index (dynamic_images, i);
-                       if (mono_mempool_contains_addr (image->mempool, ptr))
-                               owner = image;
-               }
-       }
-
-       dynamic_images_unlock ();
-
-       return owner;
-}
-
 void
 mono_reflection_init (void)
 {
-       mono_os_mutex_init (&dynamic_images_mutex);
-}
-
-static inline void
-dynamic_image_lock (MonoDynamicImage *image)
-{
-       MONO_ENTER_GC_SAFE;
-       mono_image_lock ((MonoImage*)image);
-       MONO_EXIT_GC_SAFE;
-}
-
-static inline void
-dynamic_image_unlock (MonoDynamicImage *image)
-{
-       mono_image_unlock ((MonoImage*)image);
+       mono_reflection_emit_init ();
 }
 
-static void
-register_dyn_token (MonoDynamicImage *assembly, guint32 token, MonoObject *obj)
+/*
+ * mono_class_get_ref_info:
+ *
+ *   Return the type builder/generic param builder corresponding to KLASS, if it exists.
+ */
+gpointer
+mono_class_get_ref_info (MonoClass *klass)
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
-       dynamic_image_lock (assembly);
-       mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), obj);
-       dynamic_image_unlock (assembly);
+       if (klass->ref_info_handle == 0)
+               return NULL;
+       else
+               return mono_gchandle_get_target (klass->ref_info_handle);
 }
 
-static MonoObject*
-lookup_dyn_token (MonoDynamicImage *assembly, guint32 token)
+void
+mono_class_set_ref_info (MonoClass *klass, gpointer obj)
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
-       MonoObject *obj;
-
-       dynamic_image_lock (assembly);
-       obj = (MonoObject *)mono_g_hash_table_lookup (assembly->tokens, GUINT_TO_POINTER (token));
-       dynamic_image_unlock (assembly);
-
-       return obj;
+       klass->ref_info_handle = mono_gchandle_new ((MonoObject*)obj, FALSE);
+       g_assert (klass->ref_info_handle != 0);
 }
 
-static void
-sigbuffer_init (SigBuffer *buf, int size)
+void
+mono_class_free_ref_info (MonoClass *klass)
 {
        MONO_REQ_GC_NEUTRAL_MODE;
 
-       buf->buf = (char *)g_malloc (size);
-       buf->p = buf->buf;
-       buf->end = buf->buf + size;
+       if (klass->ref_info_handle) {
+               mono_gchandle_free (klass->ref_info_handle);
+               klass->ref_info_handle = 0;
+       }
 }
 
-static void
-sigbuffer_make_room (SigBuffer *buf, int size)
+
+void
+mono_custom_attrs_free (MonoCustomAttrInfo *ainfo)
 {
        MONO_REQ_GC_NEUTRAL_MODE;
 
-       if (buf->end - buf->p < size) {
-               int new_size = buf->end - buf->buf + size + 32;
-               char *p = (char *)g_realloc (buf->buf, new_size);
-               size = buf->p - buf->buf;
-               buf->buf = p;
-               buf->p = p + size;
-               buf->end = buf->buf + new_size;
-       }
+       if (ainfo && !ainfo->cached)
+               g_free (ainfo);
 }
 
-static void
-sigbuffer_add_value (SigBuffer *buf, guint32 val)
+
+gboolean
+reflected_equal (gconstpointer a, gconstpointer b)
 {
-       MONO_REQ_GC_NEUTRAL_MODE;
+       const ReflectedEntry *ea = (const ReflectedEntry *)a;
+       const ReflectedEntry *eb = (const ReflectedEntry *)b;
 
-       sigbuffer_make_room (buf, 6);
-       mono_metadata_encode_value (val, buf->p, &buf->p);
+       return (ea->item == eb->item) && (ea->refclass == eb->refclass);
 }
 
-static void
-sigbuffer_add_byte (SigBuffer *buf, guint8 val)
-{
-       MONO_REQ_GC_NEUTRAL_MODE;
-
-       sigbuffer_make_room (buf, 1);
-       buf->p [0] = val;
-       buf->p++;
+guint
+reflected_hash (gconstpointer a) {
+       const ReflectedEntry *ea = (const ReflectedEntry *)a;
+       return mono_aligned_addr_hash (ea->item);
 }
 
+
 static void
-sigbuffer_add_mem (SigBuffer *buf, char *p, guint32 size)
+clear_cached_object (MonoDomain *domain, gpointer o, MonoClass *klass)
 {
-       MONO_REQ_GC_NEUTRAL_MODE;
+       mono_domain_lock (domain);
+       if (domain->refobject_hash) {
+        ReflectedEntry pe;
+               gpointer orig_pe, orig_value;
 
-       sigbuffer_make_room (buf, size);
-       memcpy (buf->p, p, size);
-       buf->p += size;
+               pe.item = o;
+               pe.refclass = klass;
+               if (mono_g_hash_table_lookup_extended (domain->refobject_hash, &pe, &orig_pe, &orig_value)) {
+                       mono_g_hash_table_remove (domain->refobject_hash, &pe);
+                       FREE_REFENTRY (orig_pe);
+               }
+       }
+       mono_domain_unlock (domain);
 }
 
+#ifdef REFENTRY_REQUIRES_CLEANUP
 static void
-sigbuffer_free (SigBuffer *buf)
+cleanup_refobject_hash (gpointer key, gpointer value, gpointer user_data)
 {
-       MONO_REQ_GC_NEUTRAL_MODE;
-
-       g_free (buf->buf);
+       FREE_REFENTRY (key);
 }
+#endif
 
-#ifndef DISABLE_REFLECTION_EMIT
-/**
- * mp_g_alloc:
- *
- * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
- * from the C heap.
- */
-static gpointer
-image_g_malloc (MonoImage *image, guint size)
+void
+mono_reflection_cleanup_domain (MonoDomain *domain)
 {
-       MONO_REQ_GC_NEUTRAL_MODE;
-
-       if (image)
-               return mono_image_alloc (image, size);
-       else
-               return g_malloc (size);
+       if (domain->refobject_hash) {
+/*let's avoid scanning the whole hashtable if not needed*/
+#ifdef REFENTRY_REQUIRES_CLEANUP
+               mono_g_hash_table_foreach (domain->refobject_hash, cleanup_refobject_hash, NULL);
+#endif
+               mono_g_hash_table_destroy (domain->refobject_hash);
+               domain->refobject_hash = NULL;
+       }
 }
-#endif /* !DISABLE_REFLECTION_EMIT */
 
-/**
- * image_g_alloc0:
+
+/*
+ * mono_assembly_get_object:
+ * @domain: an app domain
+ * @assembly: an assembly
  *
- * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
- * from the C heap.
+ * Return an System.Reflection.Assembly object representing the MonoAssembly @assembly.
  */
-static gpointer
-image_g_malloc0 (MonoImage *image, guint size)
+MonoReflectionAssembly*
+mono_assembly_get_object (MonoDomain *domain, MonoAssembly *assembly)
 {
-       MONO_REQ_GC_NEUTRAL_MODE;
-
-       if (image)
-               return mono_image_alloc0 (image, size);
-       else
-               return g_malloc0 (size);
+       MonoError error;
+       MonoReflectionAssembly *result;
+       result = mono_assembly_get_object_checked (domain, assembly, &error);
+       mono_error_cleanup (&error); /* FIXME new API that doesn't swallow the error */
+       return result;
 }
-
-/**
- * image_g_free:
- * @image: a MonoImage
- * @ptr: pointer
+/*
+ * mono_assembly_get_object_checked:
+ * @domain: an app domain
+ * @assembly: an assembly
  *
- * If @image is NULL, free @ptr, otherwise do nothing.
+ * Return an System.Reflection.Assembly object representing the MonoAssembly @assembly.
  */
-static void
-image_g_free (MonoImage *image, gpointer ptr)
+MonoReflectionAssembly*
+mono_assembly_get_object_checked (MonoDomain *domain, MonoAssembly *assembly, MonoError *error)
 {
-       if (image == NULL)
-               g_free (ptr);
-}
+       MonoReflectionAssembly *res;
+       
+       mono_error_init (error);
 
-#ifndef DISABLE_REFLECTION_EMIT
-static char*
-image_strdup (MonoImage *image, const char *s)
-{
-       MONO_REQ_GC_NEUTRAL_MODE;
+       CHECK_OBJECT (MonoReflectionAssembly *, assembly, NULL);
+       res = (MonoReflectionAssembly *)mono_object_new_checked (domain, mono_class_get_mono_assembly_class (), error);
+       if (!res)
+               return NULL;
+       res->assembly = assembly;
 
-       if (image)
-               return mono_image_strdup (image, s);
-       else
-               return g_strdup (s);
+       CACHE_OBJECT (MonoReflectionAssembly *, assembly, res, NULL);
 }
-#endif
-
-#define image_g_new(image,struct_type, n_structs)              \
-    ((struct_type *) image_g_malloc (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
 
-#define image_g_new0(image,struct_type, n_structs)             \
-    ((struct_type *) image_g_malloc0 (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
 
 
-static void
-alloc_table (MonoDynamicTable *table, guint nrows)
+MonoReflectionModule*   
+mono_module_get_object   (MonoDomain *domain, MonoImage *image)
 {
-       MONO_REQ_GC_NEUTRAL_MODE;
-
-       table->rows = nrows;
-       g_assert (table->columns);
-       if (nrows + 1 >= table->alloc_rows) {
-               while (nrows + 1 >= table->alloc_rows) {
-                       if (table->alloc_rows == 0)
-                               table->alloc_rows = 16;
-                       else
-                               table->alloc_rows *= 2;
-               }
-
-               table->values = (guint32 *)g_renew (guint32, table->values, (table->alloc_rows) * table->columns);
-       }
+       MonoError error;
+       MonoReflectionModule *result;
+       result = mono_module_get_object_checked (domain, image, &error);
+       mono_error_cleanup (&error);
+       return result;
 }
 
-static void
-make_room_in_stream (MonoDynamicStream *stream, int size)
+MonoReflectionModule*
+mono_module_get_object_checked (MonoDomain *domain, MonoImage *image, MonoError *error)
 {
-       MONO_REQ_GC_NEUTRAL_MODE;
-
-       if (size <= stream->alloc_size)
-               return;
-       
-       while (stream->alloc_size <= size) {
-               if (stream->alloc_size < 4096)
-                       stream->alloc_size = 4096;
-               else
-                       stream->alloc_size *= 2;
-       }
+       MonoReflectionModule *res;
+       char* basename;
        
-       stream->data = (char *)g_realloc (stream->data, stream->alloc_size);
-}
-
-static guint32
-string_heap_insert (MonoDynamicStream *sh, const char *str)
-{
-       MONO_REQ_GC_NEUTRAL_MODE;
-
-       guint32 idx;
-       guint32 len;
-       gpointer oldkey, oldval;
+       mono_error_init (error);
+       CHECK_OBJECT (MonoReflectionModule *, image, NULL);
+       res = (MonoReflectionModule *)mono_object_new_checked (domain, mono_class_get_mono_module_class (), error);
+       if (!res)
+               return NULL;
 
-       if (g_hash_table_lookup_extended (sh->hash, str, &oldkey, &oldval))
-               return GPOINTER_TO_UINT (oldval);
+       res->image = image;
+       MonoReflectionAssembly *assm_obj = mono_assembly_get_object_checked (domain, image->assembly, error);
+       if (!assm_obj)
+               return NULL;
+       MONO_OBJECT_SETREF (res, assembly, assm_obj);
 
-       len = strlen (str) + 1;
-       idx = sh->index;
+       MONO_OBJECT_SETREF (res, fqname, mono_string_new (domain, image->name));
+       basename = g_path_get_basename (image->name);
+       MONO_OBJECT_SETREF (res, name, mono_string_new (domain, basename));
+       MONO_OBJECT_SETREF (res, scopename, mono_string_new (domain, image->module_name));
        
-       make_room_in_stream (sh, idx + len);
-
-       /*
-        * We strdup the string even if we already copy them in sh->data
-        * so that the string pointers in the hash remain valid even if
-        * we need to realloc sh->data. We may want to avoid that later.
-        */
-       g_hash_table_insert (sh->hash, g_strdup (str), GUINT_TO_POINTER (idx));
-       memcpy (sh->data + idx, str, len);
-       sh->index += len;
-       return idx;
-}
+       g_free (basename);
 
-static guint32
-string_heap_insert_mstring (MonoDynamicStream *sh, MonoString *str, MonoError *error)
-{
-       MONO_REQ_GC_UNSAFE_MODE;
+       if (image->assembly->image == image) {
+               res->token = mono_metadata_make_token (MONO_TABLE_MODULE, 1);
+       } else {
+               int i;
+               res->token = 0;
+               if (image->assembly->image->modules) {
+                       for (i = 0; i < image->assembly->image->module_count; i++) {
+                               if (image->assembly->image->modules [i] == image)
+                                       res->token = mono_metadata_make_token (MONO_TABLE_MODULEREF, i + 1);
+                       }
+                       g_assert (res->token);
+               }
+       }
 
-       mono_error_init (error);
-       char *name = mono_string_to_utf8_checked (str, error);
-       return_val_if_nok (error, -1);
-       guint32 idx;
-       idx = string_heap_insert (sh, name);
-       g_free (name);
-       return idx;
+       CACHE_OBJECT (MonoReflectionModule *, image, res, NULL);
 }
 
-#ifndef DISABLE_REFLECTION_EMIT
-static void
-string_heap_init (MonoDynamicStream *sh)
+MonoReflectionModule*
+mono_module_file_get_object (MonoDomain *domain, MonoImage *image, int table_index)
 {
-       MONO_REQ_GC_NEUTRAL_MODE;
-
-       sh->index = 0;
-       sh->alloc_size = 4096;
-       sh->data = (char *)g_malloc (4096);
-       sh->hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-       string_heap_insert (sh, "");
+       MonoError error;
+       MonoReflectionModule *result;
+       result = mono_module_file_get_object_checked (domain, image, table_index, &error);
+       mono_error_cleanup (&error);
+       return result;
 }
-#endif
 
-static guint32
-mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
+MonoReflectionModule*
+mono_module_file_get_object_checked (MonoDomain *domain, MonoImage *image, int table_index, MonoError *error)
 {
-       MONO_REQ_GC_NEUTRAL_MODE;
-
-       guint32 idx;
+       MonoReflectionModule *res;
+       MonoTableInfo *table;
+       guint32 cols [MONO_FILE_SIZE];
+       const char *name;
+       guint32 i, name_idx;
+       const char *val;
        
-       make_room_in_stream (stream, stream->index + len);
-       memcpy (stream->data + stream->index, data, len);
-       idx = stream->index;
-       stream->index += len;
-       /* 
-        * align index? Not without adding an additional param that controls it since
-        * we may store a blob value in pieces.
-        */
-       return idx;
-}
+       mono_error_init (error);
 
-static guint32
-mono_image_add_stream_zero (MonoDynamicStream *stream, guint32 len)
-{
-       MONO_REQ_GC_NEUTRAL_MODE;
-
-       guint32 idx;
-       
-       make_room_in_stream (stream, stream->index + len);
-       memset (stream->data + stream->index, 0, len);
-       idx = stream->index;
-       stream->index += len;
-       return idx;
-}
-
-static void
-stream_data_align (MonoDynamicStream *stream)
-{
-       MONO_REQ_GC_NEUTRAL_MODE;
-
-       char buf [4] = {0};
-       guint32 count = stream->index % 4;
+       res = (MonoReflectionModule *)mono_object_new_checked (domain, mono_class_get_mono_module_class (), error);
+       if (!res)
+               return NULL;
 
-       /* we assume the stream data will be aligned */
-       if (count)
-               mono_image_add_stream_data (stream, buf, 4 - count);
-}
+       table = &image->tables [MONO_TABLE_FILE];
+       g_assert (table_index < table->rows);
+       mono_metadata_decode_row (table, table_index, cols, MONO_FILE_SIZE);
 
-#ifndef DISABLE_REFLECTION_EMIT
-static int
-mono_blob_entry_hash (const char* str)
-{
-       MONO_REQ_GC_NEUTRAL_MODE;
+       res->image = NULL;
+       MonoReflectionAssembly *assm_obj = mono_assembly_get_object_checked (domain, image->assembly, error);
+       if (!assm_obj)
+               return NULL;
+       MONO_OBJECT_SETREF (res, assembly, assm_obj);
+       name = mono_metadata_string_heap (image, cols [MONO_FILE_NAME]);
 
-       guint len, h;
-       const char *end;
-       len = mono_metadata_decode_blob_size (str, &str);
-       if (len > 0) {
-               end = str + len;
-               h = *str;
-               for (str += 1; str < end; str++)
-                       h = (h << 5) - h + *str;
-               return h;
-       } else {
-               return 0;
+       /* Check whenever the row has a corresponding row in the moduleref table */
+       table = &image->tables [MONO_TABLE_MODULEREF];
+       for (i = 0; i < table->rows; ++i) {
+               name_idx = mono_metadata_decode_row_col (table, i, MONO_MODULEREF_NAME);
+               val = mono_metadata_string_heap (image, name_idx);
+               if (strcmp (val, name) == 0)
+                       res->image = image->modules [i];
        }
-}
-
-static gboolean
-mono_blob_entry_equal (const char *str1, const char *str2) {
-       MONO_REQ_GC_NEUTRAL_MODE;
 
-       int len, len2;
-       const char *end1;
-       const char *end2;
-       len = mono_metadata_decode_blob_size (str1, &end1);
-       len2 = mono_metadata_decode_blob_size (str2, &end2);
-       if (len != len2)
-               return 0;
-       return memcmp (end1, end2, len) == 0;
-}
-#endif
-static guint32
-add_to_blob_cached (MonoDynamicImage *assembly, char *b1, int s1, char *b2, int s2)
-{
-       MONO_REQ_GC_NEUTRAL_MODE;
-
-       guint32 idx;
-       char *copy;
-       gpointer oldkey, oldval;
+       MONO_OBJECT_SETREF (res, fqname, mono_string_new (domain, name));
+       MONO_OBJECT_SETREF (res, name, mono_string_new (domain, name));
+       MONO_OBJECT_SETREF (res, scopename, mono_string_new (domain, name));
+       res->is_resource = cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA;
+       res->token = mono_metadata_make_token (MONO_TABLE_FILE, table_index + 1);
 
-       copy = (char *)g_malloc (s1+s2);
-       memcpy (copy, b1, s1);
-       memcpy (copy + s1, b2, s2);
-       if (g_hash_table_lookup_extended (assembly->blob_cache, copy, &oldkey, &oldval)) {
-               g_free (copy);
-               idx = GPOINTER_TO_UINT (oldval);
-       } else {
-               idx = mono_image_add_stream_data (&assembly->blob, b1, s1);
-               mono_image_add_stream_data (&assembly->blob, b2, s2);
-               g_hash_table_insert (assembly->blob_cache, copy, GUINT_TO_POINTER (idx));
-       }
-       return idx;
+       return res;
 }
 
-static guint32
-sigbuffer_add_to_blob_cached (MonoDynamicImage *assembly, SigBuffer *buf)
+static gboolean
+verify_safe_for_managed_space (MonoType *type)
 {
-       MONO_REQ_GC_NEUTRAL_MODE;
-
-       char blob_size [8];
-       char *b = blob_size;
-       guint32 size = buf->p - buf->buf;
-       /* store length */
-       g_assert (size <= (buf->end - buf->buf));
-       mono_metadata_encode_value (size, b, &b);
-       return add_to_blob_cached (assembly, blob_size, b-blob_size, buf->buf, size);
-}
-
-/*
- * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
- * dest may be misaligned.
- */
-static void
-swap_with_size (char *dest, const char* val, int len, int nelem) {
-       MONO_REQ_GC_NEUTRAL_MODE;
-#if G_BYTE_ORDER != G_LITTLE_ENDIAN
-       int elem;
-
-       for (elem = 0; elem < nelem; ++elem) {
-               switch (len) {
-               case 1:
-                       *dest = *val;
-                       break;
-               case 2:
-                       dest [0] = val [1];
-                       dest [1] = val [0];
-                       break;
-               case 4:
-                       dest [0] = val [3];
-                       dest [1] = val [2];
-                       dest [2] = val [1];
-                       dest [3] = val [0];
-                       break;
-               case 8:
-                       dest [0] = val [7];
-                       dest [1] = val [6];
-                       dest [2] = val [5];
-                       dest [3] = val [4];
-                       dest [4] = val [3];
-                       dest [5] = val [2];
-                       dest [6] = val [1];
-                       dest [7] = val [0];
+       switch (type->type) {
+#ifdef DEBUG_HARDER
+       case MONO_TYPE_ARRAY:
+               return verify_safe_for_managed_space (&type->data.array->eklass->byval_arg);
+       case MONO_TYPE_PTR:
+               return verify_safe_for_managed_space (type->data.type);
+       case MONO_TYPE_SZARRAY:
+               return verify_safe_for_managed_space (&type->data.klass->byval_arg);
+       case MONO_TYPE_GENERICINST: {
+               MonoGenericInst *inst = type->data.generic_class->inst;
+               int i;
+               if (!inst->is_open)
                        break;
-               default:
-                       g_assert_not_reached ();
-               }
-               dest += len;
-               val += len;
+               for (i = 0; i < inst->type_argc; ++i)
+                       if (!verify_safe_for_managed_space (inst->type_argv [i]))
+                               return FALSE;
+               return TRUE;
        }
-#else
-       memcpy (dest, val, len * nelem);
 #endif
+       case MONO_TYPE_VAR:
+       case MONO_TYPE_MVAR:
+               return TRUE;
+       default:
+               return TRUE;
+       }
 }
 
-static guint32
-add_mono_string_to_blob_cached (MonoDynamicImage *assembly, MonoString *str)
+static MonoType*
+mono_type_normalize (MonoType *type)
 {
-       MONO_REQ_GC_UNSAFE_MODE;
-       
-       char blob_size [64];
-       char *b = blob_size;
-       guint32 idx = 0, len;
+       int i;
+       MonoGenericClass *gclass;
+       MonoGenericInst *ginst;
+       MonoClass *gtd;
+       MonoGenericContainer *gcontainer;
+       MonoType **argv = NULL;
+       gboolean is_denorm_gtd = TRUE, requires_rebind = FALSE;
 
-       len = str->length * 2;
-       mono_metadata_encode_value (len, b, &b);
-#if G_BYTE_ORDER != G_LITTLE_ENDIAN
-       {
-               char *swapped = g_malloc (2 * mono_string_length (str));
-               const char *p = (const char*)mono_string_chars (str);
+       if (type->type != MONO_TYPE_GENERICINST)
+               return type;
+
+       gclass = type->data.generic_class;
+       ginst = gclass->context.class_inst;
+       if (!ginst->is_open)
+               return type;
+
+       gtd = gclass->container_class;
+       gcontainer = gtd->generic_container;
+       argv = g_newa (MonoType*, ginst->type_argc);
 
-               swap_with_size (swapped, p, 2, mono_string_length (str));
-               idx = add_to_blob_cached (assembly, blob_size, b-blob_size, swapped, len);
-               g_free (swapped);
+       for (i = 0; i < ginst->type_argc; ++i) {
+               MonoType *t = ginst->type_argv [i], *norm;
+               if (t->type != MONO_TYPE_VAR || t->data.generic_param->num != i || t->data.generic_param->owner != gcontainer)
+                       is_denorm_gtd = FALSE;
+               norm = mono_type_normalize (t);
+               argv [i] = norm;
+               if (norm != t)
+                       requires_rebind = TRUE;
        }
-#else
-       idx = add_to_blob_cached (assembly, blob_size, b-blob_size, (char*)mono_string_chars (str), len);
-#endif
-       return idx;
-}
 
-#ifndef DISABLE_REFLECTION_EMIT
-static MonoClass *
-default_class_from_mono_type (MonoType *type)
-{
-       MONO_REQ_GC_NEUTRAL_MODE;
+       if (is_denorm_gtd)
+               return type->byref == gtd->byval_arg.byref ? &gtd->byval_arg : &gtd->this_arg;
 
-       switch (type->type) {
-       case MONO_TYPE_OBJECT:
-               return mono_defaults.object_class;
-       case MONO_TYPE_VOID:
-               return mono_defaults.void_class;
-       case MONO_TYPE_BOOLEAN:
-               return mono_defaults.boolean_class;
-       case MONO_TYPE_CHAR:
-               return mono_defaults.char_class;
-       case MONO_TYPE_I1:
-               return mono_defaults.sbyte_class;
-       case MONO_TYPE_U1:
-               return mono_defaults.byte_class;
-       case MONO_TYPE_I2:
-               return mono_defaults.int16_class;
-       case MONO_TYPE_U2:
-               return mono_defaults.uint16_class;
-       case MONO_TYPE_I4:
-               return mono_defaults.int32_class;
-       case MONO_TYPE_U4:
-               return mono_defaults.uint32_class;
-       case MONO_TYPE_I:
-               return mono_defaults.int_class;
-       case MONO_TYPE_U:
-               return mono_defaults.uint_class;
-       case MONO_TYPE_I8:
-               return mono_defaults.int64_class;
-       case MONO_TYPE_U8:
-               return mono_defaults.uint64_class;
-       case MONO_TYPE_R4:
-               return mono_defaults.single_class;
-       case MONO_TYPE_R8:
-               return mono_defaults.double_class;
-       case MONO_TYPE_STRING:
-               return mono_defaults.string_class;
-       default:
-               g_warning ("default_class_from_mono_type: implement me 0x%02x\n", type->type);
-               g_assert_not_reached ();
+       if (requires_rebind) {
+               MonoClass *klass = mono_class_bind_generic_parameters (gtd, ginst->type_argc, argv, gclass->is_dynamic);
+               return type->byref == klass->byval_arg.byref ? &klass->byval_arg : &klass->this_arg;
        }
-       
-       return NULL;
-}
-#endif
 
+       return type;
+}
 /*
- * mono_class_get_ref_info:
+ * mono_type_get_object:
+ * @domain: an app domain
+ * @type: a type
  *
- *   Return the type builder/generic param builder corresponding to KLASS, if it exists.
+ * Return an System.MonoType object representing the type @type.
  */
-gpointer
-mono_class_get_ref_info (MonoClass *klass)
+MonoReflectionType*
+mono_type_get_object (MonoDomain *domain, MonoType *type)
 {
-       MONO_REQ_GC_UNSAFE_MODE;
+       MonoError error;
+       MonoReflectionType *ret = mono_type_get_object_checked (domain, type, &error);
+       mono_error_cleanup (&error);
 
-       if (klass->ref_info_handle == 0)
-               return NULL;
-       else
-               return mono_gchandle_get_target (klass->ref_info_handle);
+       return ret;
 }
 
-void
-mono_class_set_ref_info (MonoClass *klass, gpointer obj)
+MonoReflectionType*
+mono_type_get_object_checked (MonoDomain *domain, MonoType *type, MonoError *error)
 {
-       MONO_REQ_GC_UNSAFE_MODE;
+       MonoType *norm_type;
+       MonoReflectionType *res;
+       MonoClass *klass;
 
-       klass->ref_info_handle = mono_gchandle_new ((MonoObject*)obj, FALSE);
-       g_assert (klass->ref_info_handle != 0);
-}
+       mono_error_init (error);
 
-void
-mono_class_free_ref_info (MonoClass *klass)
-{
-       MONO_REQ_GC_NEUTRAL_MODE;
+       klass = mono_class_from_mono_type (type);
 
-       if (klass->ref_info_handle) {
-               mono_gchandle_free (klass->ref_info_handle);
-               klass->ref_info_handle = 0;
-       }
-}
+       /*we must avoid using @type as it might have come
+        * from a mono_metadata_type_dup and the caller
+        * expects that is can be freed.
+        * Using the right type from 
+        */
+       type = klass->byval_arg.byref == type->byref ? &klass->byval_arg : &klass->this_arg;
 
-static void
-encode_generic_class (MonoDynamicImage *assembly, MonoGenericClass *gclass, SigBuffer *buf)
-{
-       MONO_REQ_GC_NEUTRAL_MODE;
+       /* void is very common */
+       if (type->type == MONO_TYPE_VOID && domain->typeof_void)
+               return (MonoReflectionType*)domain->typeof_void;
 
-       int i;
-       MonoGenericInst *class_inst;
-       MonoClass *klass;
+       /*
+        * If the vtable of the given class was already created, we can use
+        * the MonoType from there and avoid all locking and hash table lookups.
+        * 
+        * We cannot do this for TypeBuilders as mono_reflection_create_runtime_class expects
+        * that the resulting object is different.   
+        */
+       if (type == &klass->byval_arg && !image_is_dynamic (klass->image)) {
+               MonoVTable *vtable = mono_class_try_get_vtable (domain, klass);
+               if (vtable && vtable->type)
+                       return (MonoReflectionType *)vtable->type;
+       }
 
-       g_assert (gclass);
+       mono_loader_lock (); /*FIXME mono_class_init and mono_class_vtable acquire it*/
+       mono_domain_lock (domain);
+       if (!domain->type_hash)
+               domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mono_metadata_type_hash, 
+                               (GCompareFunc)mono_metadata_type_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection types table");
+       if ((res = (MonoReflectionType *)mono_g_hash_table_lookup (domain->type_hash, type))) {
+               mono_domain_unlock (domain);
+               mono_loader_unlock ();
+               return res;
+       }
 
-       class_inst = gclass->context.class_inst;
+       /*Types must be normalized so a generic instance of the GTD get's the same inner type.
+        * For example in: Foo<A,B>; Bar<A> : Foo<A, Bar<A>>
+        * The second Bar will be encoded a generic instance of Bar with <A> as parameter.
+        * On all other places, Bar<A> will be encoded as the GTD itself. This is an implementation
+        * artifact of how generics are encoded and should be transparent to managed code so we
+        * need to weed out this diference when retrieving managed System.Type objects.
+        */
+       norm_type = mono_type_normalize (type);
+       if (norm_type != type) {
+               res = mono_type_get_object_checked (domain, norm_type, error);
+               if (!mono_error_ok (error))
+                       return NULL;
+               mono_g_hash_table_insert (domain->type_hash, type, res);
+               mono_domain_unlock (domain);
+               mono_loader_unlock ();
+               return res;
+       }
 
-       sigbuffer_add_value (buf, MONO_TYPE_GENERICINST);
-       klass = gclass->container_class;
-       sigbuffer_add_value (buf, klass->byval_arg.type);
-       sigbuffer_add_value (buf, mono_image_typedef_or_ref_full (assembly, &klass->byval_arg, FALSE));
+       /* This MonoGenericClass hack is no longer necessary. Let's leave it here until we finish with the 2-stage type-builder setup.*/
+       if ((type->type == MONO_TYPE_GENERICINST) && type->data.generic_class->is_dynamic && !type->data.generic_class->container_class->wastypebuilder)
+               g_assert (0);
 
-       sigbuffer_add_value (buf, class_inst->type_argc);
-       for (i = 0; i < class_inst->type_argc; ++i)
-               encode_type (assembly, class_inst->type_argv [i], buf);
+       if (!verify_safe_for_managed_space (type)) {
+               mono_domain_unlock (domain);
+               mono_loader_unlock ();
+               mono_error_set_generic_error (error, "System", "InvalidOperationException", "This type cannot be propagated to managed space");
+               return NULL;
+       }
 
-}
+       if (mono_class_get_ref_info (klass) && !klass->wastypebuilder) {
+               gboolean is_type_done = TRUE;
+               /* Generic parameters have reflection_info set but they are not finished together with their enclosing type.
+                * We must ensure that once a type is finished we don't return a GenericTypeParameterBuilder.
+                * We can't simply close the types as this will interfere with other parts of the generics machinery.
+               */
+               if (klass->byval_arg.type == MONO_TYPE_MVAR || klass->byval_arg.type == MONO_TYPE_VAR) {
+                       MonoGenericParam *gparam = klass->byval_arg.data.generic_param;
 
-static void
-encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf)
-{
-       MONO_REQ_GC_NEUTRAL_MODE;
+                       if (gparam->owner && gparam->owner->is_method) {
+                               MonoMethod *method = gparam->owner->owner.method;
+                               if (method && mono_class_get_generic_type_definition (method->klass)->wastypebuilder)
+                                       is_type_done = FALSE;
+                       } else if (gparam->owner && !gparam->owner->is_method) {
+                               MonoClass *klass = gparam->owner->owner.klass;
+                               if (klass && mono_class_get_generic_type_definition (klass)->wastypebuilder)
+                                       is_type_done = FALSE;
+                       }
+               } 
 
-       if (!type) {
-               g_assert_not_reached ();
-               return;
-       }
-               
-       if (type->byref)
-               sigbuffer_add_value (buf, MONO_TYPE_BYREF);
-
-       switch (type->type){
-       case MONO_TYPE_VOID:
-       case MONO_TYPE_BOOLEAN:
-       case MONO_TYPE_CHAR:
-       case MONO_TYPE_I1:
-       case MONO_TYPE_U1:
-       case MONO_TYPE_I2:
-       case MONO_TYPE_U2:
-       case MONO_TYPE_I4:
-       case MONO_TYPE_U4:
-       case MONO_TYPE_I8:
-       case MONO_TYPE_U8:
-       case MONO_TYPE_R4:
-       case MONO_TYPE_R8:
-       case MONO_TYPE_I:
-       case MONO_TYPE_U:
-       case MONO_TYPE_STRING:
-       case MONO_TYPE_OBJECT:
-       case MONO_TYPE_TYPEDBYREF:
-               sigbuffer_add_value (buf, type->type);
-               break;
-       case MONO_TYPE_PTR:
-               sigbuffer_add_value (buf, type->type);
-               encode_type (assembly, type->data.type, buf);
-               break;
-       case MONO_TYPE_SZARRAY:
-               sigbuffer_add_value (buf, type->type);
-               encode_type (assembly, &type->data.klass->byval_arg, buf);
-               break;
-       case MONO_TYPE_VALUETYPE:
-       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);
-                       encode_generic_class (assembly, gclass, buf);
-               } else {
-                       /*
-                        * Make sure we use the correct type.
-                        */
-                       sigbuffer_add_value (buf, k->byval_arg.type);
-                       /*
-                        * ensure only non-byref gets passed to mono_image_typedef_or_ref(),
-                        * otherwise two typerefs could point to the same type, leading to
-                        * verification errors.
-                        */
-                       sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, &k->byval_arg));
+               /* g_assert_not_reached (); */
+               /* should this be considered an error condition? */
+               if (is_type_done && !type->byref) {
+                       mono_domain_unlock (domain);
+                       mono_loader_unlock ();
+                       return (MonoReflectionType *)mono_class_get_ref_info (klass);
                }
-               break;
-       }
-       case MONO_TYPE_ARRAY:
-               sigbuffer_add_value (buf, type->type);
-               encode_type (assembly, &type->data.array->eklass->byval_arg, buf);
-               sigbuffer_add_value (buf, type->data.array->rank);
-               sigbuffer_add_value (buf, 0); /* FIXME: set to 0 for now */
-               sigbuffer_add_value (buf, 0);
-               break;
-       case MONO_TYPE_GENERICINST:
-               encode_generic_class (assembly, type->data.generic_class, buf);
-               break;
-       case MONO_TYPE_VAR:
-       case MONO_TYPE_MVAR:
-               sigbuffer_add_value (buf, type->type);
-               sigbuffer_add_value (buf, mono_type_get_generic_param_num (type));
-               break;
-       default:
-               g_error ("need to encode type %x", type->type);
        }
-}
-
-static void
-encode_reflection_type (MonoDynamicImage *assembly, MonoReflectionType *type, SigBuffer *buf, MonoError *error)
-{
-       MONO_REQ_GC_UNSAFE_MODE;
+       /* This is stored in vtables/JITted code so it has to be pinned */
+       res = (MonoReflectionType *)mono_object_new_pinned (domain, mono_defaults.runtimetype_class, error);
+       if (!mono_error_ok (error))
+               return NULL;
 
-       mono_error_init (error);
+       res->type = type;
+       mono_g_hash_table_insert (domain->type_hash, type, res);
 
-       if (!type) {
-               sigbuffer_add_value (buf, MONO_TYPE_VOID);
-               return;
-       }
+       if (type->type == MONO_TYPE_VOID)
+               domain->typeof_void = (MonoObject*)res;
 
-       MonoType *t = mono_reflection_type_get_handle (type, error);
-       return_if_nok (error);
-       encode_type (assembly, t, buf);
+       mono_domain_unlock (domain);
+       mono_loader_unlock ();
+       return res;
 }
 
-static void
-encode_custom_modifiers (MonoDynamicImage *assembly, MonoArray *modreq, MonoArray *modopt, SigBuffer *buf, MonoError *error)
+/*
+ * mono_method_get_object:
+ * @domain: an app domain
+ * @method: a method
+ * @refclass: the reflected type (can be NULL)
+ *
+ * Return an System.Reflection.MonoMethod object representing the method @method.
+ */
+MonoReflectionMethod*
+mono_method_get_object (MonoDomain *domain, MonoMethod *method, MonoClass *refclass)
 {
-       MONO_REQ_GC_UNSAFE_MODE;
-
-       int i;
-
-       mono_error_init (error);
-
-       if (modreq) {
-               for (i = 0; i < mono_array_length (modreq); ++i) {
-                       MonoType *mod = mono_type_array_get_and_resolve (modreq, i, error);
-                       return_if_nok (error);
-                       sigbuffer_add_byte (buf, MONO_TYPE_CMOD_REQD);
-                       sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod));
-               }
-       }
-       if (modopt) {
-               for (i = 0; i < mono_array_length (modopt); ++i) {
-                       MonoType *mod = mono_type_array_get_and_resolve (modopt, i, error);
-                       return_if_nok (error);
-                       sigbuffer_add_byte (buf, MONO_TYPE_CMOD_OPT);
-                       sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod));
-               }
-       }
+       MonoError error;
+       MonoReflectionMethod *ret = NULL;
+       ret = mono_method_get_object_checked (domain, method, refclass, &error);
+       mono_error_cleanup (&error);
+       return ret;
 }
 
-#ifndef DISABLE_REFLECTION_EMIT
-static guint32
-method_encode_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
+/*
+ * mono_method_get_object_checked:
+ * @domain: an app domain
+ * @method: a method
+ * @refclass: the reflected type (can be NULL)
+ * @error: set on error.
+ *
+ * Return an System.Reflection.MonoMethod object representing the method @method.
+ * Returns NULL and sets @error on error.
+ */
+MonoReflectionMethod*
+mono_method_get_object_checked (MonoDomain *domain, MonoMethod *method, MonoClass *refclass, MonoError *error)
 {
-       MONO_REQ_GC_UNSAFE_MODE;
-
-       SigBuffer buf;
-       int i;
-       guint32 nparams =  sig->param_count;
-       guint32 idx;
-
-       if (!assembly->save)
-               return 0;
-
-       sigbuffer_init (&buf, 32);
        /*
-        * FIXME: vararg, explicit_this, differenc call_conv values...
+        * We use the same C representation for methods and constructors, but the type 
+        * name in C# is different.
         */
-       idx = sig->call_convention;
-       if (sig->hasthis)
-               idx |= 0x20; /* hasthis */
-       if (sig->generic_param_count)
-               idx |= 0x10; /* generic */
-       sigbuffer_add_byte (&buf, idx);
-       if (sig->generic_param_count)
-               sigbuffer_add_value (&buf, sig->generic_param_count);
-       sigbuffer_add_value (&buf, nparams);
-       encode_type (assembly, sig->ret, &buf);
-       for (i = 0; i < nparams; ++i) {
-               if (i == sig->sentinelpos)
-                       sigbuffer_add_byte (&buf, MONO_TYPE_SENTINEL);
-               encode_type (assembly, sig->params [i], &buf);
-       }
-       idx = sigbuffer_add_to_blob_cached (assembly, &buf);
-       sigbuffer_free (&buf);
-       return idx;
-}
-#endif
-
-static guint32
-method_builder_encode_signature (MonoDynamicImage *assembly, ReflectionMethodBuilder *mb, MonoError *error)
-{
-       MONO_REQ_GC_UNSAFE_MODE;
+       MonoReflectionType *rt;
+       MonoClass *klass;
+       MonoReflectionMethod *ret;
 
        mono_error_init (error);
 
-       /*
-        * FIXME: reuse code from method_encode_signature().
-        */
-       SigBuffer buf;
-       int i;
-       guint32 nparams =  mb->parameters ? mono_array_length (mb->parameters): 0;
-       guint32 ngparams = mb->generic_params ? mono_array_length (mb->generic_params): 0;
-       guint32 notypes = mb->opt_types ? mono_array_length (mb->opt_types): 0;
-       guint32 idx;
-
-       sigbuffer_init (&buf, 32);
-       /* LAMESPEC: all the call conv spec is foobared */
-       idx = mb->call_conv & 0x60; /* has-this, explicit-this */
-       if (mb->call_conv & 2)
-               idx |= 0x5; /* vararg */
-       if (!(mb->attrs & METHOD_ATTRIBUTE_STATIC))
-               idx |= 0x20; /* hasthis */
-       if (ngparams)
-               idx |= 0x10; /* generic */
-       sigbuffer_add_byte (&buf, idx);
-       if (ngparams)
-               sigbuffer_add_value (&buf, ngparams);
-       sigbuffer_add_value (&buf, nparams + notypes);
-       encode_custom_modifiers (assembly, mb->return_modreq, mb->return_modopt, &buf, error);
-       if (!is_ok (error))
-               goto leave;
-       encode_reflection_type (assembly, mb->rtype, &buf, error);
-       if (!is_ok (error))
-               goto leave;
-       for (i = 0; i < nparams; ++i) {
-               MonoArray *modreq = NULL;
-               MonoArray *modopt = NULL;
-               MonoReflectionType *pt;
-
-               if (mb->param_modreq && (i < mono_array_length (mb->param_modreq)))
-                       modreq = mono_array_get (mb->param_modreq, MonoArray*, i);
-               if (mb->param_modopt && (i < mono_array_length (mb->param_modopt)))
-                       modopt = mono_array_get (mb->param_modopt, MonoArray*, i);
-               encode_custom_modifiers (assembly, modreq, modopt, &buf, error);
-               if (!is_ok (error))
-                       goto leave;
-               pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
-               encode_reflection_type (assembly, pt, &buf, error);
-               if (!is_ok (error))
-                       goto leave;
-       }
-       if (notypes)
-               sigbuffer_add_byte (&buf, MONO_TYPE_SENTINEL);
-       for (i = 0; i < notypes; ++i) {
-               MonoReflectionType *pt;
+       if (method->is_inflated) {
+               MonoReflectionGenericMethod *gret;
 
-               pt = mono_array_get (mb->opt_types, MonoReflectionType*, i);
-               encode_reflection_type (assembly, pt, &buf, error);
-               if (!is_ok (error))
+               if (!refclass)
+                       refclass = method->klass;
+               CHECK_OBJECT (MonoReflectionMethod *, method, refclass);
+               if ((*method->name == '.') && (!strcmp (method->name, ".ctor") || !strcmp (method->name, ".cctor"))) {
+                       klass = mono_class_get_mono_generic_cmethod_class ();
+               } else {
+                       klass = mono_class_get_mono_generic_method_class ();
+               }
+               gret = (MonoReflectionGenericMethod*)mono_object_new_checked (domain, klass, error);
+               if (!mono_error_ok (error))
                        goto leave;
-       }
-
-       idx = sigbuffer_add_to_blob_cached (assembly, &buf);
-leave:
-       sigbuffer_free (&buf);
-       return idx;
-}
+               gret->method.method = method;
 
-static guint32
-encode_locals (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, MonoError *error)
-{
-       MONO_REQ_GC_UNSAFE_MODE;
+               MONO_OBJECT_SETREF (gret, method.name, mono_string_new (domain, method->name));
 
-       mono_error_init (error);
+               rt = mono_type_get_object_checked (domain, &refclass->byval_arg, error);
+               if (!mono_error_ok (error))
+                   goto leave;
 
-       MonoDynamicTable *table;
-       guint32 *values;
-       guint32 idx, sig_idx;
-       guint nl = mono_array_length (ilgen->locals);
-       SigBuffer buf;
-       int i;
+               MONO_OBJECT_SETREF (gret, method.reftype, rt);
 
-       sigbuffer_init (&buf, 32);
-       sigbuffer_add_value (&buf, 0x07);
-       sigbuffer_add_value (&buf, nl);
-       for (i = 0; i < nl; ++i) {
-               MonoReflectionLocalBuilder *lb = mono_array_get (ilgen->locals, MonoReflectionLocalBuilder*, i);
-               
-               if (lb->is_pinned)
-                       sigbuffer_add_value (&buf, MONO_TYPE_PINNED);
-               
-               encode_reflection_type (assembly, (MonoReflectionType*)lb->type, &buf, error);
-               if (!is_ok (error)) {
-                       sigbuffer_free (&buf);
-                       return 0;
-               }
+               CACHE_OBJECT (MonoReflectionMethod *, method, (MonoReflectionMethod*)gret, refclass);
        }
-       sig_idx = sigbuffer_add_to_blob_cached (assembly, &buf);
-       sigbuffer_free (&buf);
 
-       if (assembly->standalonesig_cache == NULL)
-               assembly->standalonesig_cache = g_hash_table_new (NULL, NULL);
-       idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->standalonesig_cache, GUINT_TO_POINTER (sig_idx)));
-       if (idx)
-               return idx;
+       if (!refclass)
+               refclass = method->klass;
+
+       CHECK_OBJECT (MonoReflectionMethod *, method, refclass);
+       if (*method->name == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0)) {
+               klass = mono_class_get_mono_cmethod_class ();
+       }
+       else {
+               klass = mono_class_get_mono_method_class ();
+       }
+       ret = (MonoReflectionMethod*)mono_object_new_checked (domain, klass, error);
+       if (!mono_error_ok (error))
+               goto leave;
+       ret->method = method;
 
-       table = &assembly->tables [MONO_TABLE_STANDALONESIG];
-       idx = table->next_idx ++;
-       table->rows ++;
-       alloc_table (table, table->rows);
-       values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
+       rt = mono_type_get_object_checked (domain, &refclass->byval_arg, error);
+       if (!mono_error_ok (error))
+               goto leave;
 
-       values [MONO_STAND_ALONE_SIGNATURE] = sig_idx;
+       MONO_OBJECT_SETREF (ret, reftype, rt);
 
-       g_hash_table_insert (assembly->standalonesig_cache, GUINT_TO_POINTER (sig_idx), GUINT_TO_POINTER (idx));
+       CACHE_OBJECT (MonoReflectionMethod *, method, ret, refclass);
 
-       return idx;
+leave:
+       g_assert (!mono_error_ok (error));
+       return NULL;
 }
 
-static guint32
-method_count_clauses (MonoReflectionILGen *ilgen)
+/*
+ * mono_method_clear_object:
+ *
+ *   Clear the cached reflection objects for the dynamic method METHOD.
+ */
+void
+mono_method_clear_object (MonoDomain *domain, MonoMethod *method)
 {
-       MONO_REQ_GC_UNSAFE_MODE;
-
-       guint32 num_clauses = 0;
-       int i;
+       MonoClass *klass;
+       g_assert (method_is_dynamic (method));
 
-       MonoILExceptionInfo *ex_info;
-       for (i = 0; i < mono_array_length (ilgen->ex_handlers); ++i) {
-               ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
-               if (ex_info->handlers)
-                       num_clauses += mono_array_length (ex_info->handlers);
-               else
-                       num_clauses++;
+       klass = method->klass;
+       while (klass) {
+               clear_cached_object (domain, method, klass);
+               klass = klass->parent;
+       }
+       /* Added by mono_param_get_objects () */
+       clear_cached_object (domain, &(method->signature), NULL);
+       klass = method->klass;
+       while (klass) {
+               clear_cached_object (domain, &(method->signature), klass);
+               klass = klass->parent;
        }
-
-       return num_clauses;
 }
 
-#ifndef DISABLE_REFLECTION_EMIT
-static MonoExceptionClause*
-method_encode_clauses (MonoImage *image, MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, guint32 num_clauses, MonoError *error)
+/*
+ * mono_field_get_object:
+ * @domain: an app domain
+ * @klass: a type
+ * @field: a field
+ *
+ * Return an System.Reflection.MonoField object representing the field @field
+ * in class @klass.
+ */
+MonoReflectionField*
+mono_field_get_object (MonoDomain *domain, MonoClass *klass, MonoClassField *field)
 {
-       MONO_REQ_GC_UNSAFE_MODE;
-
-       mono_error_init (error);
-
-       MonoExceptionClause *clauses;
-       MonoExceptionClause *clause;
-       MonoILExceptionInfo *ex_info;
-       MonoILExceptionBlock *ex_block;
-       guint32 finally_start;
-       int i, j, clause_index;;
-
-       clauses = image_g_new0 (image, MonoExceptionClause, num_clauses);
-
-       clause_index = 0;
-       for (i = mono_array_length (ilgen->ex_handlers) - 1; i >= 0; --i) {
-               ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
-               finally_start = ex_info->start + ex_info->len;
-               if (!ex_info->handlers)
-                       continue;
-               for (j = 0; j < mono_array_length (ex_info->handlers); ++j) {
-                       ex_block = (MonoILExceptionBlock*)mono_array_addr (ex_info->handlers, MonoILExceptionBlock, j);
-                       clause = &(clauses [clause_index]);
-
-                       clause->flags = ex_block->type;
-                       clause->try_offset = ex_info->start;
-
-                       if (ex_block->type == MONO_EXCEPTION_CLAUSE_FINALLY)
-                               clause->try_len = finally_start - ex_info->start;
-                       else
-                               clause->try_len = ex_info->len;
-                       clause->handler_offset = ex_block->start;
-                       clause->handler_len = ex_block->len;
-                       if (ex_block->extype) {
-                               MonoType *extype = mono_reflection_type_get_handle ((MonoReflectionType*)ex_block->extype, error);
-
-                               if (!is_ok (error)) {
-                                       image_g_free (image, clauses);
-                                       return NULL;
-                               }
-                               clause->data.catch_class = mono_class_from_mono_type (extype);
-                       } else {
-                               if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
-                                       clause->data.filter_offset = ex_block->filter_offset;
-                               else
-                                       clause->data.filter_offset = 0;
-                       }
-                       finally_start = ex_block->start + ex_block->len;
-
-                       clause_index ++;
-               }
-       }
-
-       return clauses;
+       MonoError error;
+       MonoReflectionField *result;
+       result = mono_field_get_object_checked (domain, klass, field, &error);
+       mono_error_cleanup (&error);
+       return result;
 }
-#endif /* !DISABLE_REFLECTION_EMIT */
 
-/**
- * method_encode_code:
- *
- * @assembly the assembly
- * @mb the managed MethodBuilder
- * @error set on error
+/*
+ * mono_field_get_object_checked:
+ * @domain: an app domain
+ * @klass: a type
+ * @field: a field
+ * @error: set on error
  *
- * Note that the return value is not sensible if @error is set.
+ * Return an System.Reflection.MonoField object representing the field @field
+ * in class @klass. On error, returns NULL and sets @error.
  */
-static guint32
-method_encode_code (MonoDynamicImage *assembly, ReflectionMethodBuilder *mb, MonoError *error)
+MonoReflectionField*
+mono_field_get_object_checked (MonoDomain *domain, MonoClass *klass, MonoClassField *field, MonoError *error)
 {
-       MONO_REQ_GC_UNSAFE_MODE;
-
-       char flags = 0;
-       guint32 idx;
-       guint32 code_size;
-       gint32 max_stack, i;
-       gint32 num_locals = 0;
-       gint32 num_exception = 0;
-       gint maybe_small;
-       guint32 fat_flags;
-       char fat_header [12];
-       guint32 int_value;
-       guint16 short_value;
-       guint32 local_sig = 0;
-       guint32 header_size = 12;
-       MonoArray *code;
+       MonoReflectionType *rt;
+       MonoReflectionField *res;
 
        mono_error_init (error);
 
-       if ((mb->attrs & (METHOD_ATTRIBUTE_PINVOKE_IMPL | METHOD_ATTRIBUTE_ABSTRACT)) ||
-                       (mb->iattrs & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME)))
-               return 0;
-
-       /*if (mb->name)
-               g_print ("Encode method %s\n", mono_string_to_utf8 (mb->name));*/
-       if (mb->ilgen) {
-               code = mb->ilgen->code;
-               code_size = mb->ilgen->code_len;
-               max_stack = mb->ilgen->max_stack;
-               num_locals = mb->ilgen->locals ? mono_array_length (mb->ilgen->locals) : 0;
-               if (mb->ilgen->ex_handlers)
-                       num_exception = method_count_clauses (mb->ilgen);
-       } else {
-               code = mb->code;
-               if (code == NULL){
-                       MonoError inner_error;
-                       char *name = mono_string_to_utf8_checked (mb->name, &inner_error);
-                       if (!is_ok (&inner_error)) {
-                               name = g_strdup ("");
-                               mono_error_cleanup (&inner_error);
-                       }
-                       char *str = g_strdup_printf ("Method %s does not have any IL associated", name);
-                       mono_error_set_argument (error, NULL, "a method does not have any IL associated");
-                       g_free (str);
-                       g_free (name);
-                       return 0;
-               }
-
-               code_size = mono_array_length (code);
-               max_stack = 8; /* we probably need to run a verifier on the code... */
-       }
+       CHECK_OBJECT (MonoReflectionField *, field, klass);
+       res = (MonoReflectionField *)mono_object_new_checked (domain, mono_class_get_mono_field_class (), error);
+       if (!res)
+               return NULL;
+       res->klass = klass;
+       res->field = field;
+       MONO_OBJECT_SETREF (res, name, mono_string_new (domain, mono_field_get_name (field)));
 
-       stream_data_align (&assembly->code);
+       if (field->type) {
+               rt = mono_type_get_object_checked (domain, field->type, error);
+               if (!mono_error_ok (error))
+                       return NULL;
 
-       /* check for exceptions, maxstack, locals */
-       maybe_small = (max_stack <= 8) && (!num_locals) && (!num_exception);
-       if (maybe_small) {
-               if (code_size < 64 && !(code_size & 1)) {
-                       flags = (code_size << 2) | 0x2;
-               } else if (code_size < 32 && (code_size & 1)) {
-                       flags = (code_size << 2) | 0x6; /* LAMESPEC: see metadata.c */
-               } else {
-                       goto fat_header;
-               }
-               idx = mono_image_add_stream_data (&assembly->code, &flags, 1);
-               /* add to the fixup todo list */
-               if (mb->ilgen && mb->ilgen->num_token_fixups)
-                       mono_g_hash_table_insert (assembly->token_fixups, mb->ilgen, GUINT_TO_POINTER (idx + 1));
-               mono_image_add_stream_data (&assembly->code, mono_array_addr (code, char, 0), code_size);
-               return assembly->text_rva + idx;
-       } 
-fat_header:
-       if (num_locals) {
-               local_sig = MONO_TOKEN_SIGNATURE | encode_locals (assembly, mb->ilgen, error);
-               return_val_if_nok (error, 0);
-       }
-       /* 
-        * FIXME: need to set also the header size in fat_flags.
-        * (and more sects and init locals flags)
-        */
-       fat_flags =  0x03;
-       if (num_exception)
-               fat_flags |= METHOD_HEADER_MORE_SECTS;
-       if (mb->init_locals)
-               fat_flags |= METHOD_HEADER_INIT_LOCALS;
-       fat_header [0] = fat_flags;
-       fat_header [1] = (header_size / 4 ) << 4;
-       short_value = GUINT16_TO_LE (max_stack);
-       memcpy (fat_header + 2, &short_value, 2);
-       int_value = GUINT32_TO_LE (code_size);
-       memcpy (fat_header + 4, &int_value, 4);
-       int_value = GUINT32_TO_LE (local_sig);
-       memcpy (fat_header + 8, &int_value, 4);
-       idx = mono_image_add_stream_data (&assembly->code, fat_header, 12);
-       /* add to the fixup todo list */
-       if (mb->ilgen && mb->ilgen->num_token_fixups)
-               mono_g_hash_table_insert (assembly->token_fixups, mb->ilgen, GUINT_TO_POINTER (idx + 12));
-       
-       mono_image_add_stream_data (&assembly->code, mono_array_addr (code, char, 0), code_size);
-       if (num_exception) {
-               unsigned char sheader [4];
-               MonoILExceptionInfo * ex_info;
-               MonoILExceptionBlock * ex_block;
-               int j;
-
-               stream_data_align (&assembly->code);
-               /* always use fat format for now */
-               sheader [0] = METHOD_HEADER_SECTION_FAT_FORMAT | METHOD_HEADER_SECTION_EHTABLE;
-               num_exception *= 6 * sizeof (guint32);
-               num_exception += 4; /* include the size of the header */
-               sheader [1] = num_exception & 0xff;
-               sheader [2] = (num_exception >> 8) & 0xff;
-               sheader [3] = (num_exception >> 16) & 0xff;
-               mono_image_add_stream_data (&assembly->code, (char*)sheader, 4);
-               /* fat header, so we are already aligned */
-               /* reverse order */
-               for (i = mono_array_length (mb->ilgen->ex_handlers) - 1; i >= 0; --i) {
-                       ex_info = (MonoILExceptionInfo *)mono_array_addr (mb->ilgen->ex_handlers, MonoILExceptionInfo, i);
-                       if (ex_info->handlers) {
-                               int finally_start = ex_info->start + ex_info->len;
-                               for (j = 0; j < mono_array_length (ex_info->handlers); ++j) {
-                                       guint32 val;
-                                       ex_block = (MonoILExceptionBlock*)mono_array_addr (ex_info->handlers, MonoILExceptionBlock, j);
-                                       /* the flags */
-                                       val = GUINT32_TO_LE (ex_block->type);
-                                       mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
-                                       /* try offset */
-                                       val = GUINT32_TO_LE (ex_info->start);
-                                       mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
-                                       /* need fault, too, probably */
-                                       if (ex_block->type == MONO_EXCEPTION_CLAUSE_FINALLY)
-                                               val = GUINT32_TO_LE (finally_start - ex_info->start);
-                                       else
-                                               val = GUINT32_TO_LE (ex_info->len);
-                                       mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
-                                       /* handler offset */
-                                       val = GUINT32_TO_LE (ex_block->start);
-                                       mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
-                                       /* handler len */
-                                       val = GUINT32_TO_LE (ex_block->len);
-                                       mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
-                                       finally_start = ex_block->start + ex_block->len;
-                                       if (ex_block->extype) {
-                                               MonoType *extype = mono_reflection_type_get_handle ((MonoReflectionType*)ex_block->extype, error);
-                                               return_val_if_nok (error, 0);
-
-                                               val = mono_metadata_token_from_dor (mono_image_typedef_or_ref (assembly, extype));
-                                       } else {
-                                               if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
-                                                       val = ex_block->filter_offset;
-                                               else
-                                                       val = 0;
-                                       }
-                                       val = GUINT32_TO_LE (val);
-                                       mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
-                                       /*g_print ("out clause %d: from %d len=%d, handler at %d, %d, finally_start=%d, ex_info->start=%d, ex_info->len=%d, ex_block->type=%d, j=%d, i=%d\n", 
-                                                       clause.flags, clause.try_offset, clause.try_len, clause.handler_offset, clause.handler_len, finally_start, ex_info->start, ex_info->len, ex_block->type, j, i);*/
-                               }
-                       } else {
-                               g_error ("No clauses for ex info block %d", i);
-                       }
-               }
+               MONO_OBJECT_SETREF (res, type, rt);
        }
-       return assembly->text_rva + idx;
+       res->attrs = mono_field_get_flags (field);
+       CACHE_OBJECT (MonoReflectionField *, field, res, klass);
 }
 
-static guint32
-find_index_in_table (MonoDynamicImage *assembly, int table_idx, int col, guint32 token)
+/*
+ * mono_property_get_object:
+ * @domain: an app domain
+ * @klass: a type
+ * @property: a property
+ *
+ * Return an System.Reflection.MonoProperty object representing the property @property
+ * in class @klass.
+ */
+MonoReflectionProperty*
+mono_property_get_object (MonoDomain *domain, MonoClass *klass, MonoProperty *property)
 {
-       MONO_REQ_GC_NEUTRAL_MODE;
-
-       int i;
-       MonoDynamicTable *table;
-       guint32 *values;
-       
-       table = &assembly->tables [table_idx];
-
-       g_assert (col < table->columns);
-
-       values = table->values + table->columns;
-       for (i = 1; i <= table->rows; ++i) {
-               if (values [col] == token)
-                       return i;
-               values += table->columns;
-       }
-       return 0;
+       MonoError error;
+       MonoReflectionProperty *result;
+       result = mono_property_get_object_checked (domain, klass, property, &error);
+       mono_error_cleanup (&error);
+       return result;
 }
 
-/*
- * LOCKING: Acquires the loader lock. 
+/**
+ * mono_property_get_object:
+ * @domain: an app domain
+ * @klass: a type
+ * @property: a property
+ * @error: set on error
+ *
+ * Return an System.Reflection.MonoProperty object representing the property @property
+ * in class @klass.  On error returns NULL and sets @error.
  */
-static MonoCustomAttrInfo*
-lookup_custom_attr (MonoImage *image, gpointer member)
+MonoReflectionProperty*
+mono_property_get_object_checked (MonoDomain *domain, MonoClass *klass, MonoProperty *property, MonoError *error)
 {
-       MONO_REQ_GC_NEUTRAL_MODE;
-
-       MonoCustomAttrInfo* res;
+       MonoReflectionProperty *res;
 
-       res = (MonoCustomAttrInfo *)mono_image_property_lookup (image, member, MONO_PROP_DYNAMIC_CATTR);
+       mono_error_init (error);
 
+       CHECK_OBJECT (MonoReflectionProperty *, property, klass);
+       res = (MonoReflectionProperty *)mono_object_new_checked (domain, mono_class_get_mono_property_class (), error);
        if (!res)
                return NULL;
-
-       res = (MonoCustomAttrInfo *)g_memdup (res, MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * res->num_attrs);
-       res->cached = 0;
-       return res;
+       res->klass = klass;
+       res->property = property;
+       CACHE_OBJECT (MonoReflectionProperty *, property, res, klass);
 }
 
-static gboolean
-custom_attr_visible (MonoImage *image, MonoReflectionCustomAttr *cattr)
+/*
+ * mono_event_get_object:
+ * @domain: an app domain
+ * @klass: a type
+ * @event: a event
+ *
+ * Return an System.Reflection.MonoEvent object representing the event @event
+ * in class @klass.
+ */
+MonoReflectionEvent*
+mono_event_get_object (MonoDomain *domain, MonoClass *klass, MonoEvent *event)
 {
-       MONO_REQ_GC_UNSAFE_MODE;
-
-       /* 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;
-
-               if ((visibility != TYPE_ATTRIBUTE_PUBLIC) && (visibility != TYPE_ATTRIBUTE_NESTED_PUBLIC))
-                       return FALSE;
-       }
-
-       return TRUE;
+       MonoError error;
+       MonoReflectionEvent *result;
+       result = mono_event_get_object_checked (domain, klass, event, &error);
+       mono_error_cleanup (&error);
+       return result;
 }
 
-static MonoCustomAttrInfo*
-mono_custom_attrs_from_builders (MonoImage *alloc_img, MonoImage *image, MonoArray *cattrs)
+/**
+ * mono_event_get_object_checked:
+ * @domain: an app domain
+ * @klass: a type
+ * @event: a event
+ * @error: set on error
+ *
+ * Return an System.Reflection.MonoEvent object representing the event @event
+ * in class @klass. On failure sets @error and returns NULL
+ */
+MonoReflectionEvent*
+mono_event_get_object_checked (MonoDomain *domain, MonoClass *klass, MonoEvent *event, MonoError *error)
 {
-       MONO_REQ_GC_UNSAFE_MODE;
-
-       int i, index, count, not_visible;
-       MonoCustomAttrInfo *ainfo;
-       MonoReflectionCustomAttr *cattr;
+       MonoReflectionEvent *res;
+       MonoReflectionMonoEvent *mono_event;
 
-       if (!cattrs)
+       mono_error_init (error);
+       CHECK_OBJECT (MonoReflectionEvent *, event, klass);
+       mono_event = (MonoReflectionMonoEvent *)mono_object_new_checked (domain, mono_class_get_mono_event_class (), error);
+       if (!mono_event)
                return NULL;
-       /* FIXME: check in assembly the Run flag is set */
-
-       count = mono_array_length (cattrs);
-
-       /* Skip nonpublic attributes since MS.NET seems to do the same */
-       /* FIXME: This needs to be done more globally */
-       not_visible = 0;
-       for (i = 0; i < count; ++i) {
-               cattr = (MonoReflectionCustomAttr*)mono_array_get (cattrs, gpointer, i);
-               if (!custom_attr_visible (image, cattr))
-                       not_visible ++;
-       }
-
-       int num_attrs = count - not_visible;
-       ainfo = (MonoCustomAttrInfo *)image_g_malloc0 (alloc_img, MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * num_attrs);
-
-       ainfo->image = image;
-       ainfo->num_attrs = num_attrs;
-       ainfo->cached = alloc_img != NULL;
-       index = 0;
-       for (i = 0; i < count; ++i) {
-               cattr = (MonoReflectionCustomAttr*)mono_array_get (cattrs, gpointer, i);
-               if (custom_attr_visible (image, cattr)) {
-                       unsigned char *saved = (unsigned char *)mono_image_alloc (image, mono_array_length (cattr->data));
-                       memcpy (saved, mono_array_addr (cattr->data, char, 0), mono_array_length (cattr->data));
-                       ainfo->attrs [index].ctor = cattr->ctor->method;
-                       g_assert (cattr->ctor->method);
-                       ainfo->attrs [index].data = saved;
-                       ainfo->attrs [index].data_size = mono_array_length (cattr->data);
-                       index ++;
-               }
-       }
-       g_assert (index == num_attrs && count == num_attrs + not_visible);
-
-       return ainfo;
+       mono_event->klass = klass;
+       mono_event->event = event;
+       res = (MonoReflectionEvent*)mono_event;
+       CACHE_OBJECT (MonoReflectionEvent *, event, res, klass);
 }
 
-#ifndef DISABLE_REFLECTION_EMIT
-/*
- * LOCKING: Acquires the loader lock. 
+/**
+ * mono_get_reflection_missing_object:
+ * @domain: Domain where the object lives
+ *
+ * Returns the System.Reflection.Missing.Value singleton object
+ * (of type System.Reflection.Missing).
+ *
+ * Used as the value for ParameterInfo.DefaultValue when Optional
+ * is present
  */
-static void
-mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
+static MonoObject *
+mono_get_reflection_missing_object (MonoDomain *domain)
 {
-       MONO_REQ_GC_UNSAFE_MODE;
-
-       MonoCustomAttrInfo *ainfo, *tmp;
-
-       if (!cattrs || !mono_array_length (cattrs))
-               return;
-
-       ainfo = mono_custom_attrs_from_builders (image, image, cattrs);
-
-       mono_loader_lock ();
-       tmp = (MonoCustomAttrInfo *)mono_image_property_lookup (image, obj, MONO_PROP_DYNAMIC_CATTR);
-       if (tmp)
-               mono_custom_attrs_free (tmp);
-       mono_image_property_insert (image, obj, MONO_PROP_DYNAMIC_CATTR, ainfo);
-       mono_loader_unlock ();
-
+       MonoError error;
+       MonoObject *obj;
+       static MonoClassField *missing_value_field = NULL;
+       
+       if (!missing_value_field) {
+               MonoClass *missing_klass;
+               missing_klass = mono_class_get_missing_class ();
+               mono_class_init (missing_klass);
+               missing_value_field = mono_class_get_field_from_name (missing_klass, "Value");
+               g_assert (missing_value_field);
+       }
+       obj = mono_field_get_value_object_checked (domain, missing_value_field, NULL, &error);
+       mono_error_assert_ok (&error);
+       return obj;
 }
-#endif
 
-void
-mono_custom_attrs_free (MonoCustomAttrInfo *ainfo)
+static MonoObject*
+get_dbnull (MonoDomain *domain, MonoObject **dbnull)
 {
-       MONO_REQ_GC_NEUTRAL_MODE;
+       if (!*dbnull)
+               *dbnull = mono_get_dbnull_object (domain);
+       return *dbnull;
+}
 
-       if (ainfo && !ainfo->cached)
-               g_free (ainfo);
+static MonoObject*
+get_reflection_missing (MonoDomain *domain, MonoObject **reflection_missing)
+{
+       if (!*reflection_missing)
+               *reflection_missing = mono_get_reflection_missing_object (domain);
+       return *reflection_missing;
 }
 
 /*
- * idx is the table index of the object
- * type is one of MONO_CUSTOM_ATTR_*
+ * mono_param_get_objects:
+ * @domain: an app domain
+ * @method: a method
+ *
+ * Return an System.Reflection.ParameterInfo array object representing the parameters
+ * in the method @method.
  */
-static gboolean
-mono_image_add_cattrs (MonoDynamicImage *assembly, guint32 idx, guint32 type, MonoArray *cattrs, MonoError *error)
+MonoArray*
+mono_param_get_objects_internal (MonoDomain *domain, MonoMethod *method, MonoClass *refclass, MonoError *error)
 {
-       MONO_REQ_GC_UNSAFE_MODE;
+       static MonoClass *System_Reflection_ParameterInfo;
+       static MonoClass *System_Reflection_ParameterInfo_array;
+       MonoArray *res = NULL;
+       MonoReflectionMethod *member = NULL;
+       MonoReflectionParameter *param = NULL;
+       char **names = NULL, **blobs = NULL;
+       guint32 *types = NULL;
+       MonoType *type = NULL;
+       MonoObject *dbnull = NULL;
+       MonoObject *missing = NULL;
+       MonoMarshalSpec **mspecs = NULL;
+       MonoMethodSignature *sig = NULL;
+       MonoVTable *pinfo_vtable;
+       MonoReflectionType *rt;
+       int i;
 
-       MonoDynamicTable *table;
-       MonoReflectionCustomAttr *cattr;
-       guint32 *values;
-       guint32 count, i, token;
-       char blob_size [6];
-       char *p = blob_size;
-       
        mono_error_init (error);
+       
+       if (!System_Reflection_ParameterInfo_array) {
+               MonoClass *klass;
 
-       /* it is legal to pass a NULL cattrs: we avoid to use the if in a lot of places */
-       if (!cattrs)
-               return TRUE;
-       count = mono_array_length (cattrs);
-       table = &assembly->tables [MONO_TABLE_CUSTOMATTRIBUTE];
-       table->rows += count;
-       alloc_table (table, table->rows);
-       values = table->values + table->next_idx * MONO_CUSTOM_ATTR_SIZE;
-       idx <<= MONO_CUSTOM_ATTR_BITS;
-       idx |= type;
-       for (i = 0; i < count; ++i) {
-               cattr = (MonoReflectionCustomAttr*)mono_array_get (cattrs, gpointer, i);
-               values [MONO_CUSTOM_ATTR_PARENT] = idx;
-               token = mono_image_create_token (assembly, (MonoObject*)cattr->ctor, FALSE, FALSE, error);
-               if (!mono_error_ok (error)) goto fail;
-               type = mono_metadata_token_index (token);
-               type <<= MONO_CUSTOM_ATTR_TYPE_BITS;
-               switch (mono_metadata_token_table (token)) {
-               case MONO_TABLE_METHOD:
-                       type |= MONO_CUSTOM_ATTR_TYPE_METHODDEF;
-                       /*
-                        * fixup_cattrs () needs to fix this up. We can't use image->tokens, since it contains the old token for the
-                        * method, not the one returned by mono_image_create_token ().
-                        */
-                       mono_g_hash_table_insert (assembly->remapped_tokens, GUINT_TO_POINTER (token), cattr->ctor);
-                       break;
-               case MONO_TABLE_MEMBERREF:
-                       type |= MONO_CUSTOM_ATTR_TYPE_MEMBERREF;
-                       break;
-               default:
-                       g_warning ("got wrong token in custom attr");
-                       continue;
-               }
-               values [MONO_CUSTOM_ATTR_TYPE] = type;
-               p = blob_size;
-               mono_metadata_encode_value (mono_array_length (cattr->data), p, &p);
-               values [MONO_CUSTOM_ATTR_VALUE] = add_to_blob_cached (assembly, blob_size, p - blob_size,
-                       mono_array_addr (cattr->data, char, 0), mono_array_length (cattr->data));
-               values += MONO_CUSTOM_ATTR_SIZE;
-               ++table->next_idx;
-       }
-
-       return TRUE;
-
-fail:
-       return FALSE;
-}
+               klass = mono_class_get_mono_parameter_info_class ();
 
-static void
-mono_image_add_decl_security (MonoDynamicImage *assembly, guint32 parent_token, MonoArray *permissions)
-{
-       MONO_REQ_GC_UNSAFE_MODE;
+               mono_memory_barrier ();
+               System_Reflection_ParameterInfo = klass; 
 
-       MonoDynamicTable *table;
-       guint32 *values;
-       guint32 count, i, idx;
-       MonoReflectionPermissionSet *perm;
+       
+               klass = mono_array_class_get (klass, 1);
+               mono_memory_barrier ();
+               System_Reflection_ParameterInfo_array = klass;
+       }
 
-       if (!permissions)
-               return;
+       sig = mono_method_signature_checked (method, error);
+       if (!mono_error_ok (error))
+               goto leave;
 
-       count = mono_array_length (permissions);
-       table = &assembly->tables [MONO_TABLE_DECLSECURITY];
-       table->rows += count;
-       alloc_table (table, table->rows);
+       if (!sig->param_count) {
+               res = mono_array_new_specific_checked (mono_class_vtable (domain, System_Reflection_ParameterInfo_array), 0, error);
+               if (!res)
+                       goto leave;
 
-       for (i = 0; i < mono_array_length (permissions); ++i) {
-               perm = (MonoReflectionPermissionSet*)mono_array_addr (permissions, MonoReflectionPermissionSet, i);
+               return res;
+       }
 
-               values = table->values + table->next_idx * MONO_DECL_SECURITY_SIZE;
+       /* Note: the cache is based on the address of the signature into the method
+        * since we already cache MethodInfos with the method as keys.
+        */
+       CHECK_OBJECT (MonoArray*, &(method->signature), refclass);
 
-               idx = mono_metadata_token_index (parent_token);
-               idx <<= MONO_HAS_DECL_SECURITY_BITS;
-               switch (mono_metadata_token_table (parent_token)) {
-               case MONO_TABLE_TYPEDEF:
-                       idx |= MONO_HAS_DECL_SECURITY_TYPEDEF;
-                       break;
-               case MONO_TABLE_METHOD:
-                       idx |= MONO_HAS_DECL_SECURITY_METHODDEF;
-                       break;
-               case MONO_TABLE_ASSEMBLY:
-                       idx |= MONO_HAS_DECL_SECURITY_ASSEMBLY;
-                       break;
-               default:
-                       g_assert_not_reached ();
-               }
-
-               values [MONO_DECL_SECURITY_ACTION] = perm->action;
-               values [MONO_DECL_SECURITY_PARENT] = idx;
-               values [MONO_DECL_SECURITY_PERMISSIONSET] = add_mono_string_to_blob_cached (assembly, perm->pset);
+       member = mono_method_get_object_checked (domain, method, refclass, error);
+       if (!member)
+               goto leave;
+       names = g_new (char *, sig->param_count);
+       mono_method_get_param_names (method, (const char **) names);
 
-               ++table->next_idx;
-       }
-}
+       mspecs = g_new (MonoMarshalSpec*, sig->param_count + 1);
+       mono_method_get_marshal_info (method, mspecs);
 
-/*
- * Fill in the MethodDef and ParamDef tables for a method.
- * This is used for both normal methods and constructors.
- */
-static gboolean
-mono_image_basic_method (ReflectionMethodBuilder *mb, MonoDynamicImage *assembly, MonoError *error)
-{
-       MONO_REQ_GC_UNSAFE_MODE;
+       res = mono_array_new_specific_checked (mono_class_vtable (domain, System_Reflection_ParameterInfo_array), sig->param_count, error);
+       if (!res)
+               goto leave;
 
-       MonoDynamicTable *table;
-       guint32 *values;
-       guint i, count;
+       pinfo_vtable = mono_class_vtable (domain, System_Reflection_ParameterInfo);
+       for (i = 0; i < sig->param_count; ++i) {
+               param = (MonoReflectionParameter *) mono_object_new_specific_checked (pinfo_vtable, error);
+               if (!param)
+                       goto leave;
 
-       mono_error_init (error);
+               rt = mono_type_get_object_checked (domain, sig->params [i], error);
+               if (!rt)
+                       goto leave;
 
-       /* room in this table is already allocated */
-       table = &assembly->tables [MONO_TABLE_METHOD];
-       *mb->table_idx = table->next_idx ++;
-       g_hash_table_insert (assembly->method_to_table_idx, mb->mhandle, GUINT_TO_POINTER ((*mb->table_idx)));
-       values = table->values + *mb->table_idx * MONO_METHOD_SIZE;
-       values [MONO_METHOD_NAME] = string_heap_insert_mstring (&assembly->sheap, mb->name, error);
-       return_val_if_nok (error, FALSE);
-       values [MONO_METHOD_FLAGS] = mb->attrs;
-       values [MONO_METHOD_IMPLFLAGS] = mb->iattrs;
-       values [MONO_METHOD_SIGNATURE] = method_builder_encode_signature (assembly, mb, error);
-       return_val_if_nok (error, FALSE);
-       values [MONO_METHOD_RVA] = method_encode_code (assembly, mb, error);
-       return_val_if_nok (error, FALSE);
+               MONO_OBJECT_SETREF (param, ClassImpl, rt);
 
-       table = &assembly->tables [MONO_TABLE_PARAM];
-       values [MONO_METHOD_PARAMLIST] = table->next_idx;
+               MONO_OBJECT_SETREF (param, MemberImpl, (MonoObject*)member);
 
-       mono_image_add_decl_security (assembly, 
-               mono_metadata_make_token (MONO_TABLE_METHOD, *mb->table_idx), mb->permissions);
+               MONO_OBJECT_SETREF (param, NameImpl, mono_string_new (domain, names [i]));
 
-       if (mb->pinfo) {
-               MonoDynamicTable *mtable;
-               guint32 *mvalues;
-               
-               mtable = &assembly->tables [MONO_TABLE_FIELDMARSHAL];
-               mvalues = mtable->values + mtable->next_idx * MONO_FIELD_MARSHAL_SIZE;
-               
-               count = 0;
-               for (i = 0; i < mono_array_length (mb->pinfo); ++i) {
-                       if (mono_array_get (mb->pinfo, gpointer, i))
-                               count++;
-               }
-               table->rows += count;
-               alloc_table (table, table->rows);
-               values = table->values + table->next_idx * MONO_PARAM_SIZE;
-               for (i = 0; i < mono_array_length (mb->pinfo); ++i) {
-                       MonoReflectionParamBuilder *pb;
-                       if ((pb = mono_array_get (mb->pinfo, MonoReflectionParamBuilder*, i))) {
-                               values [MONO_PARAM_FLAGS] = pb->attrs;
-                               values [MONO_PARAM_SEQUENCE] = i;
-                               if (pb->name != NULL) {
-                                       values [MONO_PARAM_NAME] = string_heap_insert_mstring (&assembly->sheap, pb->name, error);
-                                       return_val_if_nok (error, FALSE);
-                               } else {
-                                       values [MONO_PARAM_NAME] = 0;
-                               }
-                               values += MONO_PARAM_SIZE;
-                               if (pb->marshal_info) {
-                                       mtable->rows++;
-                                       alloc_table (mtable, mtable->rows);
-                                       mvalues = mtable->values + mtable->rows * MONO_FIELD_MARSHAL_SIZE;
-                                       mvalues [MONO_FIELD_MARSHAL_PARENT] = (table->next_idx << MONO_HAS_FIELD_MARSHAL_BITS) | MONO_HAS_FIELD_MARSHAL_PARAMDEF;
-                                       mvalues [MONO_FIELD_MARSHAL_NATIVE_TYPE] = encode_marshal_blob (assembly, pb->marshal_info, error);
-                                       return_val_if_nok (error, FALSE);
-                               }
-                               pb->table_idx = table->next_idx++;
-                               if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
-                                       guint32 field_type = 0;
-                                       mtable = &assembly->tables [MONO_TABLE_CONSTANT];
-                                       mtable->rows ++;
-                                       alloc_table (mtable, mtable->rows);
-                                       mvalues = mtable->values + mtable->rows * MONO_CONSTANT_SIZE;
-                                       mvalues [MONO_CONSTANT_PARENT] = MONO_HASCONSTANT_PARAM | (pb->table_idx << MONO_HASCONSTANT_BITS);
-                                       mvalues [MONO_CONSTANT_VALUE] = encode_constant (assembly, pb->def_value, &field_type);
-                                       mvalues [MONO_CONSTANT_TYPE] = field_type;
-                                       mvalues [MONO_CONSTANT_PADDING] = 0;
-                               }
-                       }
-               }
-       }
+               param->PositionImpl = i;
+               param->AttrsImpl = sig->params [i]->attrs;
 
-       return TRUE;
-}
+               if (!(param->AttrsImpl & PARAM_ATTRIBUTE_HAS_DEFAULT)) {
+                       if (param->AttrsImpl & PARAM_ATTRIBUTE_OPTIONAL)
+                               MONO_OBJECT_SETREF (param, DefaultValueImpl, get_reflection_missing (domain, &missing));
+                       else
+                               MONO_OBJECT_SETREF (param, DefaultValueImpl, get_dbnull (domain, &dbnull));
+               } else {
 
-#ifndef DISABLE_REFLECTION_EMIT
-static gboolean
-reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error)
-{
-       MONO_REQ_GC_UNSAFE_MODE;
+                       if (!blobs) {
+                               blobs = g_new0 (char *, sig->param_count);
+                               types = g_new0 (guint32, sig->param_count);
+                               get_default_param_value_blobs (method, blobs, types); 
+                       }
 
-       mono_error_init (error);
-       memset (rmb, 0, sizeof (ReflectionMethodBuilder));
+                       /* Build MonoType for the type from the Constant Table */
+                       if (!type)
+                               type = g_new0 (MonoType, 1);
+                       type->type = (MonoTypeEnum)types [i];
+                       type->data.klass = NULL;
+                       if (types [i] == MONO_TYPE_CLASS)
+                               type->data.klass = mono_defaults.object_class;
+                       else if ((sig->params [i]->type == MONO_TYPE_VALUETYPE) && sig->params [i]->data.klass->enumtype) {
+                               /* For enums, types [i] contains the base type */
 
-       rmb->ilgen = mb->ilgen;
-       rmb->rtype = mono_reflection_type_resolve_user_types ((MonoReflectionType*)mb->rtype, error);
-       return_val_if_nok (error, FALSE);
-       rmb->parameters = mb->parameters;
-       rmb->generic_params = mb->generic_params;
-       rmb->generic_container = mb->generic_container;
-       rmb->opt_types = NULL;
-       rmb->pinfo = mb->pinfo;
-       rmb->attrs = mb->attrs;
-       rmb->iattrs = mb->iattrs;
-       rmb->call_conv = mb->call_conv;
-       rmb->code = mb->code;
-       rmb->type = mb->type;
-       rmb->name = mb->name;
-       rmb->table_idx = &mb->table_idx;
-       rmb->init_locals = mb->init_locals;
-       rmb->skip_visibility = FALSE;
-       rmb->return_modreq = mb->return_modreq;
-       rmb->return_modopt = mb->return_modopt;
-       rmb->param_modreq = mb->param_modreq;
-       rmb->param_modopt = mb->param_modopt;
-       rmb->permissions = mb->permissions;
-       rmb->mhandle = mb->mhandle;
-       rmb->nrefs = 0;
-       rmb->refs = NULL;
-
-       if (mb->dll) {
-               rmb->charset = mb->charset;
-               rmb->extra_flags = mb->extra_flags;
-               rmb->native_cc = mb->native_cc;
-               rmb->dllentry = mb->dllentry;
-               rmb->dll = mb->dll;
-       }
+                                       type->type = MONO_TYPE_VALUETYPE;
+                                       type->data.klass = mono_class_from_mono_type (sig->params [i]);
+                       } else
+                               type->data.klass = mono_class_from_mono_type (type);
 
-       return TRUE;
-}
+                       MonoObject *default_val_obj = mono_get_object_from_blob (domain, type, blobs [i], error);
+                       if (!is_ok (error))
+                               goto leave;
+                       MONO_OBJECT_SETREF (param, DefaultValueImpl, default_val_obj);
 
-static gboolean
-reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
-{
-       MONO_REQ_GC_UNSAFE_MODE;
+                       /* Type in the Constant table is MONO_TYPE_CLASS for nulls */
+                       if (types [i] != MONO_TYPE_CLASS && !param->DefaultValueImpl) {
+                               if (param->AttrsImpl & PARAM_ATTRIBUTE_OPTIONAL)
+                                       MONO_OBJECT_SETREF (param, DefaultValueImpl, get_reflection_missing (domain, &missing));
+                               else
+                                       MONO_OBJECT_SETREF (param, DefaultValueImpl, get_dbnull (domain, &dbnull));
+                       }
+                       
+               }
 
-       const char *name = mb->attrs & METHOD_ATTRIBUTE_STATIC ? ".cctor": ".ctor";
+               if (mspecs [i + 1]) {
+                       MonoReflectionMarshalAsAttribute* mobj;
+                       mobj = mono_reflection_marshal_as_attribute_from_marshal_spec (domain, method->klass, mspecs [i + 1], error);
+                       if (!mobj)
+                               goto leave;
+                       MONO_OBJECT_SETREF (param, MarshalAsImpl, (MonoObject*)mobj);
+               }
+               
+               mono_array_setref (res, i, param);
+       }
 
-       mono_error_init (error);
+leave:
+       g_free (names);
+       g_free (blobs);
+       g_free (types);
+       g_free (type);
 
-       memset (rmb, 0, sizeof (ReflectionMethodBuilder));
+       if (sig) {
+               for (i = sig->param_count; i >= 0; i--) {
+                       if (mspecs [i])
+                               mono_metadata_free_marshal_spec (mspecs [i]);
+               }
+       }
+       g_free (mspecs);
 
-       rmb->ilgen = mb->ilgen;
-       rmb->rtype = mono_type_get_object_checked (mono_domain_get (), &mono_defaults.void_class->byval_arg, error);
-       return_val_if_nok (error, FALSE);
-       rmb->parameters = mb->parameters;
-       rmb->generic_params = NULL;
-       rmb->generic_container = NULL;
-       rmb->opt_types = NULL;
-       rmb->pinfo = mb->pinfo;
-       rmb->attrs = mb->attrs;
-       rmb->iattrs = mb->iattrs;
-       rmb->call_conv = mb->call_conv;
-       rmb->code = NULL;
-       rmb->type = mb->type;
-       rmb->name = mono_string_new (mono_domain_get (), name);
-       rmb->table_idx = &mb->table_idx;
-       rmb->init_locals = mb->init_locals;
-       rmb->skip_visibility = FALSE;
-       rmb->return_modreq = NULL;
-       rmb->return_modopt = NULL;
-       rmb->param_modreq = mb->param_modreq;
-       rmb->param_modopt = mb->param_modopt;
-       rmb->permissions = mb->permissions;
-       rmb->mhandle = mb->mhandle;
-       rmb->nrefs = 0;
-       rmb->refs = NULL;
-
-       return TRUE;
+       if (!is_ok (error))
+               return NULL;
+       
+       CACHE_OBJECT (MonoArray *, &(method->signature), res, refclass);
 }
 
-static void
-reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb)
+MonoArray*
+mono_param_get_objects (MonoDomain *domain, MonoMethod *method)
 {
-       MONO_REQ_GC_UNSAFE_MODE;
-
-       memset (rmb, 0, sizeof (ReflectionMethodBuilder));
-
-       rmb->ilgen = mb->ilgen;
-       rmb->rtype = mb->rtype;
-       rmb->parameters = mb->parameters;
-       rmb->generic_params = NULL;
-       rmb->generic_container = NULL;
-       rmb->opt_types = NULL;
-       rmb->pinfo = NULL;
-       rmb->attrs = mb->attrs;
-       rmb->iattrs = 0;
-       rmb->call_conv = mb->call_conv;
-       rmb->code = NULL;
-       rmb->type = (MonoObject *) mb->owner;
-       rmb->name = mb->name;
-       rmb->table_idx = NULL;
-       rmb->init_locals = mb->init_locals;
-       rmb->skip_visibility = mb->skip_visibility;
-       rmb->return_modreq = NULL;
-       rmb->return_modopt = NULL;
-       rmb->param_modreq = NULL;
-       rmb->param_modopt = NULL;
-       rmb->permissions = NULL;
-       rmb->mhandle = mb->mhandle;
-       rmb->nrefs = 0;
-       rmb->refs = NULL;
-}      
-#endif
+       MonoError error;
+       MonoArray *result = mono_param_get_objects_internal (domain, method, NULL, &error);
+       mono_error_assert_ok (&error);
+       return result;
+}
 
-static gboolean
-mono_image_add_methodimpl (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, MonoError *error)
+/*
+ * mono_method_body_get_object:
+ * @domain: an app domain
+ * @method: a method
+ *
+ * Return an System.Reflection.MethodBody object representing the method @method.
+ */
+MonoReflectionMethodBody*
+mono_method_body_get_object (MonoDomain *domain, MonoMethod *method)
 {
-       MONO_REQ_GC_UNSAFE_MODE;
+       MonoError error;
+       MonoReflectionMethodBody *result = mono_method_body_get_object_checked (domain, method, &error);
+       mono_error_cleanup (&error);
+       return result;
+}
 
-       MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mb->type;
-       MonoDynamicTable *table;
-       guint32 *values;
-       guint32 tok;
-       MonoReflectionMethod *m;
+/**
+ * mono_method_body_get_object_checked:
+ * @domain: an app domain
+ * @method: a method
+ * @error: set on error
+ *
+ * Return an System.Reflection.MethodBody object representing the
+ * method @method.  On failure, returns NULL and sets @error.
+ */
+MonoReflectionMethodBody*
+mono_method_body_get_object_checked (MonoDomain *domain, MonoMethod *method, MonoError *error)
+{
+       MonoReflectionMethodBody *ret;
+       MonoMethodHeader *header;
+       MonoImage *image;
+       MonoReflectionType *rt;
+       guint32 method_rva, local_var_sig_token;
+       char *ptr;
+       unsigned char format, flags;
        int i;
 
        mono_error_init (error);
 
-       if (!mb->override_methods)
-               return TRUE;
+       /* for compatibility with .net */
+       if (method_is_dynamic (method)) {
+               mono_error_set_generic_error (error, "System", "InvalidOperationException", "");
+               return NULL;
+       }
 
-       for (i = 0; i < mono_array_length (mb->override_methods); ++i) {
-               m = mono_array_get (mb->override_methods, MonoReflectionMethod*, i);
+       CHECK_OBJECT (MonoReflectionMethodBody *, method, NULL);
 
-               table = &assembly->tables [MONO_TABLE_METHODIMPL];
-               table->rows ++;
-               alloc_table (table, table->rows);
-               values = table->values + table->rows * MONO_METHODIMPL_SIZE;
-               values [MONO_METHODIMPL_CLASS] = tb->table_idx;
-               values [MONO_METHODIMPL_BODY] = MONO_METHODDEFORREF_METHODDEF | (mb->table_idx << MONO_METHODDEFORREF_BITS);
+       if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
+               (method->flags & METHOD_ATTRIBUTE_ABSTRACT) ||
+           (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
+               (method->klass->image->raw_data && method->klass->image->raw_data [1] != 'Z') ||
+           (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME))
+               return NULL;
 
-               tok = mono_image_create_token (assembly, (MonoObject*)m, FALSE, FALSE, error);
-               return_val_if_nok (error, FALSE);
+       image = method->klass->image;
+       header = mono_method_get_header_checked (method, error);
+       return_val_if_nok (error, NULL);
 
-               switch (mono_metadata_token_table (tok)) {
-               case MONO_TABLE_MEMBERREF:
-                       tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODREF;
+       if (!image_is_dynamic (image)) {
+               /* Obtain local vars signature token */
+               method_rva = mono_metadata_decode_row_col (&image->tables [MONO_TABLE_METHOD], mono_metadata_token_index (method->token) - 1, MONO_METHOD_RVA);
+               ptr = mono_image_rva_map (image, method_rva);
+               flags = *(const unsigned char *) ptr;
+               format = flags & METHOD_HEADER_FORMAT_MASK;
+               switch (format){
+               case METHOD_HEADER_TINY_FORMAT:
+                       local_var_sig_token = 0;
                        break;
-               case MONO_TABLE_METHOD:
-                       tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODDEF;
+               case METHOD_HEADER_FAT_FORMAT:
+                       ptr += 2;
+                       ptr += 2;
+                       ptr += 4;
+                       local_var_sig_token = read32 (ptr);
                        break;
                default:
                        g_assert_not_reached ();
                }
-               values [MONO_METHODIMPL_DECLARATION] = tok;
-       }
+       } else
+               local_var_sig_token = 0; //FIXME
 
-       return TRUE;
-}
+       ret = (MonoReflectionMethodBody*)mono_object_new_checked (domain, mono_class_get_method_body_class (), error);
+       if (!is_ok (error))
+               goto fail;
 
-#ifndef DISABLE_REFLECTION_EMIT
-static gboolean
-mono_image_get_method_info (MonoReflectionMethodBuilder *mb, MonoDynamicImage *assembly, MonoError *error)
-{
-       MONO_REQ_GC_UNSAFE_MODE;
+       ret->init_locals = header->init_locals;
+       ret->max_stack = header->max_stack;
+       ret->local_var_sig_token = local_var_sig_token;
+       MonoArray *il_arr = mono_array_new_cached (domain, mono_defaults.byte_class, header->code_size, error);
+       if (!is_ok (error))
+               goto fail;
+       MONO_OBJECT_SETREF (ret, il, il_arr);
+       memcpy (mono_array_addr (ret->il, guint8, 0), header->code, header->code_size);
 
-       MonoDynamicTable *table;
-       guint32 *values;
-       ReflectionMethodBuilder rmb;
-       int i;
+       /* Locals */
+       MonoArray *locals_arr = mono_array_new_cached (domain, mono_class_get_local_variable_info_class (), header->num_locals, error);
+       if (!is_ok (error))
+               goto fail;
+       MONO_OBJECT_SETREF (ret, locals, locals_arr);
+       for (i = 0; i < header->num_locals; ++i) {
+               MonoReflectionLocalVariableInfo *info = (MonoReflectionLocalVariableInfo*)mono_object_new_checked (domain, mono_class_get_local_variable_info_class (), error);
+               if (!is_ok (error))
+                       goto fail;
 
-       mono_error_init (error);
+               rt = mono_type_get_object_checked (domain, header->locals [i], error);
+               if (!is_ok (error))
+                       goto fail;
 
-       if (!reflection_methodbuilder_from_method_builder (&rmb, mb, error) ||
-           !mono_image_basic_method (&rmb, assembly, error))
-               return FALSE;
+               MONO_OBJECT_SETREF (info, local_type, rt);
 
-       mb->table_idx = *rmb.table_idx;
-
-       if (mb->dll) { /* It's a P/Invoke method */
-               guint32 moduleref;
-               /* map CharSet values to on-disk values */
-               int ncharset = (mb->charset ? (mb->charset - 1) * 2 : 0);
-               int extra_flags = mb->extra_flags;
-               table = &assembly->tables [MONO_TABLE_IMPLMAP];
-               table->rows ++;
-               alloc_table (table, table->rows);
-               values = table->values + table->rows * MONO_IMPLMAP_SIZE;
-               
-               values [MONO_IMPLMAP_FLAGS] = (mb->native_cc << 8) | ncharset | extra_flags;
-               values [MONO_IMPLMAP_MEMBER] = (mb->table_idx << 1) | 1; /* memberforwarded: method */
-               if (mb->dllentry) {
-                       values [MONO_IMPLMAP_NAME] = string_heap_insert_mstring (&assembly->sheap, mb->dllentry, error);
-                       return_val_if_nok (error, FALSE);
-               } else {
-                       values [MONO_IMPLMAP_NAME] = string_heap_insert_mstring (&assembly->sheap, mb->name, error);
-                       return_val_if_nok (error, FALSE);
-               }
-               moduleref = string_heap_insert_mstring (&assembly->sheap, mb->dll, error);
-               return_val_if_nok (error, FALSE);
-               if (!(values [MONO_IMPLMAP_SCOPE] = find_index_in_table (assembly, MONO_TABLE_MODULEREF, MONO_MODULEREF_NAME, moduleref))) {
-                       table = &assembly->tables [MONO_TABLE_MODULEREF];
-                       table->rows ++;
-                       alloc_table (table, table->rows);
-                       table->values [table->rows * MONO_MODULEREF_SIZE + MONO_MODULEREF_NAME] = moduleref;
-                       values [MONO_IMPLMAP_SCOPE] = table->rows;
-               }
+               info->is_pinned = header->locals [i]->pinned;
+               info->local_index = i;
+               mono_array_setref (ret->locals, i, info);
        }
 
-       if (mb->generic_params) {
-               table = &assembly->tables [MONO_TABLE_GENERICPARAM];
-               table->rows += mono_array_length (mb->generic_params);
-               alloc_table (table, table->rows);
-               for (i = 0; i < mono_array_length (mb->generic_params); ++i) {
-                       guint32 owner = MONO_TYPEORMETHOD_METHOD | (mb->table_idx << MONO_TYPEORMETHOD_BITS);
+       /* Exceptions */
+       MonoArray *exn_clauses = mono_array_new_cached (domain, mono_class_get_exception_handling_clause_class (), header->num_clauses, error);
+       if (!is_ok (error))
+               goto fail;
+       MONO_OBJECT_SETREF (ret, clauses, exn_clauses);
+       for (i = 0; i < header->num_clauses; ++i) {
+               MonoReflectionExceptionHandlingClause *info = (MonoReflectionExceptionHandlingClause*)mono_object_new_checked (domain, mono_class_get_exception_handling_clause_class (), error);
+               if (!is_ok (error))
+                       goto fail;
+               MonoExceptionClause *clause = &header->clauses [i];
 
-                       mono_image_get_generic_param_info (
-                               (MonoReflectionGenericParam *)mono_array_get (mb->generic_params, gpointer, i), owner, assembly);
-               }
-       }
-
-       return TRUE;
-}
-
-static gboolean
-mono_image_get_ctor_info (MonoDomain *domain, MonoReflectionCtorBuilder *mb, MonoDynamicImage *assembly, MonoError *error)
-{
-       MONO_REQ_GC_UNSAFE_MODE;
-
-       ReflectionMethodBuilder rmb;
-
-       if (!reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
-               return FALSE;
-
-       if (!mono_image_basic_method (&rmb, assembly, error))
-               return FALSE;
-
-       mb->table_idx = *rmb.table_idx;
-
-       return TRUE;
-}
-#endif
-
-static char*
-type_get_fully_qualified_name (MonoType *type)
-{
-       MONO_REQ_GC_NEUTRAL_MODE;
-
-       return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
-}
-
-static char*
-type_get_qualified_name (MonoType *type, MonoAssembly *ass)
-{
-       MONO_REQ_GC_UNSAFE_MODE;
+               info->flags = clause->flags;
+               info->try_offset = clause->try_offset;
+               info->try_length = clause->try_len;
+               info->handler_offset = clause->handler_offset;
+               info->handler_length = clause->handler_len;
+               if (clause->flags == MONO_EXCEPTION_CLAUSE_FILTER)
+                       info->filter_offset = clause->data.filter_offset;
+               else if (clause->data.catch_class) {
+                       rt = mono_type_get_object_checked (mono_domain_get (), &clause->data.catch_class->byval_arg, error);
+                       if (!is_ok (error))
+                               goto fail;
 
-       MonoClass *klass;
-       MonoAssembly *ta;
+                       MONO_OBJECT_SETREF (info, catch_type, rt);
+               }
 
-       klass = mono_class_from_mono_type (type);
-       if (!klass) 
-               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)
-                       /* 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
-                       return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
+               mono_array_setref (ret->clauses, i, info);
        }
 
-       return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
+       mono_metadata_free_mh (header);
+       CACHE_OBJECT (MonoReflectionMethodBody *, method, ret, NULL);
+       return ret;
+
+fail:
+       mono_metadata_free_mh (header);
+       return NULL;
 }
 
-#ifndef DISABLE_REFLECTION_EMIT
-/*field_image is the image to which the eventual custom mods have been encoded against*/
-static guint32
-fieldref_encode_signature (MonoDynamicImage *assembly, MonoImage *field_image, MonoType *type)
+/**
+ * mono_get_dbnull_object:
+ * @domain: Domain where the object lives
+ *
+ * Returns the System.DBNull.Value singleton object
+ *
+ * Used as the value for ParameterInfo.DefaultValue 
+ */
+MonoObject *
+mono_get_dbnull_object (MonoDomain *domain)
 {
-       MONO_REQ_GC_NEUTRAL_MODE;
-
-       SigBuffer buf;
-       guint32 idx, i, token;
-
-       if (!assembly->save)
-               return 0;
-
-       sigbuffer_init (&buf, 32);
+       MonoError error;
+       MonoObject *obj;
+       static MonoClassField *dbnull_value_field = NULL;
        
-       sigbuffer_add_value (&buf, 0x06);
-       /* encode custom attributes before the type */
-       if (type->num_mods) {
-               for (i = 0; i < type->num_mods; ++i) {
-                       if (field_image) {
-                               MonoError error;
-                               MonoClass *klass = mono_class_get_checked (field_image, type->modifiers [i].token, &error);
-                               g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
-
-                               token = mono_image_typedef_or_ref (assembly, &klass->byval_arg);
-                       } else {
-                               token = type->modifiers [i].token;
-                       }
-
-                       if (type->modifiers [i].required)
-                               sigbuffer_add_byte (&buf, MONO_TYPE_CMOD_REQD);
-                       else
-                               sigbuffer_add_byte (&buf, MONO_TYPE_CMOD_OPT);
-
-                       sigbuffer_add_value (&buf, token);
-               }
+       if (!dbnull_value_field) {
+               MonoClass *dbnull_klass;
+               dbnull_klass = mono_class_get_dbnull_class ();
+               dbnull_value_field = mono_class_get_field_from_name (dbnull_klass, "Value");
+               g_assert (dbnull_value_field);
        }
-       encode_type (assembly, type, &buf);
-       idx = sigbuffer_add_to_blob_cached (assembly, &buf);
-       sigbuffer_free (&buf);
-       return idx;
+       obj = mono_field_get_value_object_checked (domain, dbnull_value_field, NULL, &error);
+       mono_error_assert_ok (&error);
+       return obj;
 }
-#endif
 
-static guint32
-field_encode_signature (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb, MonoError *error)
+static void
+get_default_param_value_blobs (MonoMethod *method, char **blobs, guint32 *types)
 {
-       MONO_REQ_GC_UNSAFE_MODE;
-
-       mono_error_init (error);
-
-       SigBuffer buf;
-       guint32 idx;
-       guint32 typespec = 0;
-       MonoType *type;
-       MonoClass *klass;
-
-       init_type_builder_generics (fb->type, error);
-       return_val_if_nok (error, 0);
-
-       type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
-       return_val_if_nok (error, 0);
-       klass = mono_class_from_mono_type (type);
+       guint32 param_index, i, lastp, crow = 0;
+       guint32 param_cols [MONO_PARAM_SIZE], const_cols [MONO_CONSTANT_SIZE];
+       gint32 idx;
 
-       sigbuffer_init (&buf, 32);
-       
-       sigbuffer_add_value (&buf, 0x06);
-       encode_custom_modifiers (assembly, fb->modreq, fb->modopt, &buf, error);
-       if (!is_ok (error))
-               goto fail;
-       /* encode custom attributes before the type */
+       MonoClass *klass = method->klass;
+       MonoImage *image = klass->image;
+       MonoMethodSignature *methodsig = mono_method_signature (method);
 
-       if (klass->generic_container)
-               typespec = create_typespec (assembly, type);
+       MonoTableInfo *constt;
+       MonoTableInfo *methodt;
+       MonoTableInfo *paramt;
 
-       if (typespec) {
-               MonoGenericClass *gclass;
-               gclass = mono_metadata_lookup_generic_class (klass, klass->generic_container->context.class_inst, TRUE);
-               encode_generic_class (assembly, gclass, &buf);
-       } else {
-               encode_type (assembly, type, &buf);
-       }
-       idx = sigbuffer_add_to_blob_cached (assembly, &buf);
-       sigbuffer_free (&buf);
-       return idx;
-fail:
-       sigbuffer_free (&buf);
-       return 0;
-}
+       if (!methodsig->param_count)
+               return;
 
-static guint32
-encode_constant (MonoDynamicImage *assembly, MonoObject *val, MonoTypeEnum *ret_type)
-{
-       MONO_REQ_GC_UNSAFE_MODE;
+       mono_class_init (klass);
 
-       char blob_size [64];
-       char *b = blob_size;
-       char *box_val;
-       char* buf;
-       guint32 idx = 0, len = 0, dummy = 0;
-
-       buf = (char *)g_malloc (64);
-       if (!val) {
-               *ret_type = MONO_TYPE_CLASS;
-               len = 4;
-               box_val = (char*)&dummy;
-       } else {
-               box_val = ((char*)val) + sizeof (MonoObject);
-               *ret_type = val->vtable->klass->byval_arg.type;
-       }
-handle_enum:
-       switch (*ret_type) {
-       case MONO_TYPE_BOOLEAN:
-       case MONO_TYPE_U1:
-       case MONO_TYPE_I1:
-               len = 1;
-               break;
-       case MONO_TYPE_CHAR:
-       case MONO_TYPE_U2:
-       case MONO_TYPE_I2:
-               len = 2;
-               break;
-       case MONO_TYPE_U4:
-       case MONO_TYPE_I4:
-       case MONO_TYPE_R4:
-               len = 4;
-               break;
-       case MONO_TYPE_U8:
-       case MONO_TYPE_I8:
-               len = 8;
-               break;
-       case MONO_TYPE_R8:
-               len = 8;
-               break;
-       case MONO_TYPE_VALUETYPE: {
-               MonoClass *klass = val->vtable->klass;
-               
-               if (klass->enumtype) {
-                       *ret_type = mono_class_enum_basetype (klass)->type;
-                       goto handle_enum;
-               } else if (mono_is_corlib_image (klass->image) && strcmp (klass->name_space, "System") == 0 && strcmp (klass->name, "DateTime") == 0) {
-                       len = 8;
-               } else 
-                       g_error ("we can't encode valuetypes, we should have never reached this line");
-               break;
-       }
-       case MONO_TYPE_CLASS:
-               break;
-       case MONO_TYPE_STRING: {
-               MonoString *str = (MonoString*)val;
-               /* there is no signature */
-               len = str->length * 2;
-               mono_metadata_encode_value (len, b, &b);
-#if G_BYTE_ORDER != G_LITTLE_ENDIAN
-               {
-                       char *swapped = g_malloc (2 * mono_string_length (str));
-                       const char *p = (const char*)mono_string_chars (str);
-
-                       swap_with_size (swapped, p, 2, mono_string_length (str));
-                       idx = add_to_blob_cached (assembly, blob_size, b-blob_size, swapped, len);
-                       g_free (swapped);
+       if (image_is_dynamic (klass->image)) {
+               MonoReflectionMethodAux *aux;
+               if (method->is_inflated)
+                       method = ((MonoMethodInflated*)method)->declaring;
+               aux = (MonoReflectionMethodAux *)g_hash_table_lookup (((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
+               if (aux && aux->param_defaults) {
+                       memcpy (blobs, &(aux->param_defaults [1]), methodsig->param_count * sizeof (char*));
+                       memcpy (types, &(aux->param_default_types [1]), methodsig->param_count * sizeof (guint32));
                }
-#else
-               idx = add_to_blob_cached (assembly, blob_size, b-blob_size, (char*)mono_string_chars (str), len);
-#endif
-
-               g_free (buf);
-               return idx;
-       }
-       case MONO_TYPE_GENERICINST:
-               *ret_type = val->vtable->klass->generic_class->container_class->byval_arg.type;
-               goto handle_enum;
-       default:
-               g_error ("we don't encode constant type 0x%02x yet", *ret_type);
+               return;
        }
 
-       /* there is no signature */
-       mono_metadata_encode_value (len, b, &b);
-#if G_BYTE_ORDER != G_LITTLE_ENDIAN
-       idx = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
-       swap_with_size (blob_size, box_val, len, 1);
-       mono_image_add_stream_data (&assembly->blob, blob_size, len);
-#else
-       idx = add_to_blob_cached (assembly, blob_size, b-blob_size, box_val, len);
-#endif
-
-       g_free (buf);
-       return idx;
-}
-
-static guint32
-encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo, MonoError *error)
-{
-       MONO_REQ_GC_UNSAFE_MODE;
+       methodt = &klass->image->tables [MONO_TABLE_METHOD];
+       paramt = &klass->image->tables [MONO_TABLE_PARAM];
+       constt = &image->tables [MONO_TABLE_CONSTANT];
 
-       mono_error_init (error);
+       idx = mono_method_get_index (method) - 1;
+       g_assert (idx != -1);
 
-       char *str;
-       SigBuffer buf;
-       guint32 idx, len;
+       param_index = mono_metadata_decode_row_col (methodt, idx, MONO_METHOD_PARAMLIST);
+       if (idx + 1 < methodt->rows)
+               lastp = mono_metadata_decode_row_col (methodt, idx + 1, MONO_METHOD_PARAMLIST);
+       else
+               lastp = paramt->rows + 1;
 
-       sigbuffer_init (&buf, 32);
+       for (i = param_index; i < lastp; ++i) {
+               guint32 paramseq;
 
-       sigbuffer_add_value (&buf, minfo->type);
+               mono_metadata_decode_row (paramt, i - 1, param_cols, MONO_PARAM_SIZE);
+               paramseq = param_cols [MONO_PARAM_SEQUENCE];
 
-       switch (minfo->type) {
-       case MONO_NATIVE_BYVALTSTR:
-       case MONO_NATIVE_BYVALARRAY:
-               sigbuffer_add_value (&buf, minfo->count);
-               break;
-       case MONO_NATIVE_LPARRAY:
-               if (minfo->eltype || minfo->has_size) {
-                       sigbuffer_add_value (&buf, minfo->eltype);
-                       if (minfo->has_size) {
-                               sigbuffer_add_value (&buf, minfo->param_num != -1? minfo->param_num: 0);
-                               sigbuffer_add_value (&buf, minfo->count != -1? minfo->count: 0);
+               if (!(param_cols [MONO_PARAM_FLAGS] & PARAM_ATTRIBUTE_HAS_DEFAULT))
+                       continue;
 
-                               /* LAMESPEC: ElemMult is undocumented */
-                               sigbuffer_add_value (&buf, minfo->param_num != -1? 1: 0);
-                       }
-               }
-               break;
-       case MONO_NATIVE_SAFEARRAY:
-               if (minfo->eltype)
-                       sigbuffer_add_value (&buf, minfo->eltype);
-               break;
-       case MONO_NATIVE_CUSTOM:
-               if (minfo->guid) {
-                       str = mono_string_to_utf8_checked (minfo->guid, error);
-                       if (!is_ok (error)) {
-                               sigbuffer_free (&buf);
-                               return 0;
-                       }
-                       len = strlen (str);
-                       sigbuffer_add_value (&buf, len);
-                       sigbuffer_add_mem (&buf, str, len);
-                       g_free (str);
-               } else {
-                       sigbuffer_add_value (&buf, 0);
-               }
-               /* native type name */
-               sigbuffer_add_value (&buf, 0);
-               /* custom marshaler type name */
-               if (minfo->marshaltype || minfo->marshaltyperef) {
-                       if (minfo->marshaltyperef) {
-                               MonoType *marshaltype = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
-                               if (!is_ok (error)) {
-                                       sigbuffer_free (&buf);
-                                       return 0;
-                               }
-                               str = type_get_fully_qualified_name (marshaltype);
-                       } else {
-                               str = mono_string_to_utf8_checked (minfo->marshaltype, error);
-                               if (!is_ok (error)) {
-                                       sigbuffer_free (&buf);
-                                       return 0;
-                               }
-                       }
-                       len = strlen (str);
-                       sigbuffer_add_value (&buf, len);
-                       sigbuffer_add_mem (&buf, str, len);
-                       g_free (str);
-               } else {
-                       /* FIXME: Actually a bug, since this field is required.  Punting for now ... */
-                       sigbuffer_add_value (&buf, 0);
-               }
-               if (minfo->mcookie) {
-                       str = mono_string_to_utf8_checked (minfo->mcookie, error);
-                       if (!is_ok (error)) {
-                               sigbuffer_free (&buf);
-                               return 0;
-                       }
-                       len = strlen (str);
-                       sigbuffer_add_value (&buf, len);
-                       sigbuffer_add_mem (&buf, str, len);
-                       g_free (str);
-               } else {
-                       sigbuffer_add_value (&buf, 0);
+               crow = mono_metadata_get_constant_index (image, MONO_TOKEN_PARAM_DEF | i, crow + 1);
+               if (!crow) {
+                       continue;
                }
-               break;
-       default:
-               break;
+       
+               mono_metadata_decode_row (constt, crow - 1, const_cols, MONO_CONSTANT_SIZE);
+               blobs [paramseq - 1] = (char *)mono_metadata_blob_heap (image, const_cols [MONO_CONSTANT_VALUE]);
+               types [paramseq - 1] = const_cols [MONO_CONSTANT_TYPE];
        }
-       idx = sigbuffer_add_to_blob_cached (assembly, &buf);
-       sigbuffer_free (&buf);
-       return idx;
-}
-
-static void
-mono_image_get_field_info (MonoReflectionFieldBuilder *fb, MonoDynamicImage *assembly, MonoError *error)
-{
-       MONO_REQ_GC_UNSAFE_MODE;
-
-       mono_error_init (error);
 
-       MonoDynamicTable *table;
-       guint32 *values;
-
-       /* maybe this fixup should be done in the C# code */
-       if (fb->attrs & FIELD_ATTRIBUTE_LITERAL)
-               fb->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
-       table = &assembly->tables [MONO_TABLE_FIELD];
-       fb->table_idx = table->next_idx ++;
-       g_hash_table_insert (assembly->field_to_table_idx, fb->handle, GUINT_TO_POINTER (fb->table_idx));
-       values = table->values + fb->table_idx * MONO_FIELD_SIZE;
-       values [MONO_FIELD_NAME] = string_heap_insert_mstring (&assembly->sheap, fb->name, error);
-       return_if_nok (error);
-       values [MONO_FIELD_FLAGS] = fb->attrs;
-       values [MONO_FIELD_SIGNATURE] = field_encode_signature (assembly, fb, error);
-       return_if_nok (error);
-
-
-       if (fb->offset != -1) {
-               table = &assembly->tables [MONO_TABLE_FIELDLAYOUT];
-               table->rows ++;
-               alloc_table (table, table->rows);
-               values = table->values + table->rows * MONO_FIELD_LAYOUT_SIZE;
-               values [MONO_FIELD_LAYOUT_FIELD] = fb->table_idx;
-               values [MONO_FIELD_LAYOUT_OFFSET] = fb->offset;
-       }
-       if (fb->attrs & FIELD_ATTRIBUTE_LITERAL) {
-               MonoTypeEnum field_type = (MonoTypeEnum)0;
-               table = &assembly->tables [MONO_TABLE_CONSTANT];
-               table->rows ++;
-               alloc_table (table, table->rows);
-               values = table->values + table->rows * MONO_CONSTANT_SIZE;
-               values [MONO_CONSTANT_PARENT] = MONO_HASCONSTANT_FIEDDEF | (fb->table_idx << MONO_HASCONSTANT_BITS);
-               values [MONO_CONSTANT_VALUE] = encode_constant (assembly, fb->def_value, &field_type);
-               values [MONO_CONSTANT_TYPE] = field_type;
-               values [MONO_CONSTANT_PADDING] = 0;
-       }
-       if (fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) {
-               guint32 rva_idx;
-               table = &assembly->tables [MONO_TABLE_FIELDRVA];
-               table->rows ++;
-               alloc_table (table, table->rows);
-               values = table->values + table->rows * MONO_FIELD_RVA_SIZE;
-               values [MONO_FIELD_RVA_FIELD] = fb->table_idx;
-               /*
-                * We store it in the code section because it's simpler for now.
-                */
-               if (fb->rva_data) {
-                       if (mono_array_length (fb->rva_data) >= 10)
-                               stream_data_align (&assembly->code);
-                       rva_idx = mono_image_add_stream_data (&assembly->code, mono_array_addr (fb->rva_data, char, 0), mono_array_length (fb->rva_data));
-               } else
-                       rva_idx = mono_image_add_stream_zero (&assembly->code, mono_class_value_size (fb->handle->parent, NULL));
-               values [MONO_FIELD_RVA_RVA] = rva_idx + assembly->text_rva;
-       }
-       if (fb->marshal_info) {
-               table = &assembly->tables [MONO_TABLE_FIELDMARSHAL];
-               table->rows ++;
-               alloc_table (table, table->rows);
-               values = table->values + table->rows * MONO_FIELD_MARSHAL_SIZE;
-               values [MONO_FIELD_MARSHAL_PARENT] = (fb->table_idx << MONO_HAS_FIELD_MARSHAL_BITS) | MONO_HAS_FIELD_MARSHAL_FIELDSREF;
-               values [MONO_FIELD_MARSHAL_NATIVE_TYPE] = encode_marshal_blob (assembly, fb->marshal_info, error);
-               return_if_nok (error);
-       }
+       return;
 }
 
-static guint32
-property_encode_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBuilder *fb, MonoError *error)
+MonoObject *
+mono_get_object_from_blob (MonoDomain *domain, MonoType *type, const char *blob, MonoError *error)
 {
-       MONO_REQ_GC_UNSAFE_MODE;
+       void *retval;
+       MonoClass *klass;
+       MonoObject *object;
+       MonoType *basetype = type;
 
        mono_error_init (error);
 
-       SigBuffer buf;
-       guint32 nparams = 0;
-       MonoReflectionMethodBuilder *mb = fb->get_method;
-       MonoReflectionMethodBuilder *smb = fb->set_method;
-       guint32 idx, i;
-
-       if (mb && mb->parameters)
-               nparams = mono_array_length (mb->parameters);
-       if (!mb && smb && smb->parameters)
-               nparams = mono_array_length (smb->parameters) - 1;
-       sigbuffer_init (&buf, 32);
-       if (fb->call_conv & 0x20)
-               sigbuffer_add_byte (&buf, 0x28);
-       else
-               sigbuffer_add_byte (&buf, 0x08);
-       sigbuffer_add_value (&buf, nparams);
-       if (mb) {
-               encode_reflection_type (assembly, (MonoReflectionType*)mb->rtype, &buf, error);
-               if (!is_ok (error))
-                       goto fail;
-               for (i = 0; i < nparams; ++i) {
-                       MonoReflectionType *pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
-                       encode_reflection_type (assembly, pt, &buf, error);
-                       if (!is_ok (error))
-                               goto fail;
-               }
-       } else if (smb && smb->parameters) {
-               /* the property type is the last param */
-               encode_reflection_type (assembly, mono_array_get (smb->parameters, MonoReflectionType*, nparams), &buf, error);
-               if (!is_ok (error))
-                       goto fail;
-
-               for (i = 0; i < nparams; ++i) {
-                       MonoReflectionType *pt = mono_array_get (smb->parameters, MonoReflectionType*, i);
-                       encode_reflection_type (assembly, pt, &buf, error);
-                       if (!is_ok (error))
-                               goto fail;
-               }
+       if (!blob)
+               return NULL;
+       
+       klass = mono_class_from_mono_type (type);
+       if (klass->valuetype) {
+               object = mono_object_new_checked (domain, klass, error);
+               return_val_if_nok (error, NULL);
+               retval = ((gchar *) object + sizeof (MonoObject));
+               if (klass->enumtype)
+                       basetype = mono_class_enum_basetype (klass);
        } else {
-               encode_reflection_type (assembly, (MonoReflectionType*)fb->type, &buf, error);
-               if (!is_ok (error))
-                       goto fail;
+               retval = &object;
        }
-
-       idx = sigbuffer_add_to_blob_cached (assembly, &buf);
-       sigbuffer_free (&buf);
-       return idx;
-fail:
-       sigbuffer_free (&buf);
-       return 0;
+                       
+       if (!mono_get_constant_value_from_blob (domain, basetype->type,  blob, retval, error))
+               return object;
+       else
+               return NULL;
 }
 
-static void
-mono_image_get_property_info (MonoReflectionPropertyBuilder *pb, MonoDynamicImage *assembly, MonoError *error)
-{
-       MONO_REQ_GC_UNSAFE_MODE;
-
-       mono_error_init (error);
+static int
+assembly_name_to_aname (MonoAssemblyName *assembly, char *p) {
+       int found_sep;
+       char *s;
+       gboolean quoted = FALSE;
 
-       MonoDynamicTable *table;
-       guint32 *values;
-       guint num_methods = 0;
-       guint32 semaidx;
+       memset (assembly, 0, sizeof (MonoAssemblyName));
+       assembly->culture = "";
+       memset (assembly->public_key_token, 0, MONO_PUBLIC_KEY_TOKEN_LENGTH);
 
-       /* 
-        * we need to set things in the following tables:
-        * PROPERTYMAP (info already filled in _get_type_info ())
-        * PROPERTY    (rows already preallocated in _get_type_info ())
-        * METHOD      (method info already done with the generic method code)
-        * METHODSEMANTICS
-        * CONSTANT
-        */
-       table = &assembly->tables [MONO_TABLE_PROPERTY];
-       pb->table_idx = table->next_idx ++;
-       values = table->values + pb->table_idx * MONO_PROPERTY_SIZE;
-       values [MONO_PROPERTY_NAME] = string_heap_insert_mstring (&assembly->sheap, pb->name, error);
-       return_if_nok (error);
-       values [MONO_PROPERTY_FLAGS] = pb->attrs;
-       values [MONO_PROPERTY_TYPE] = property_encode_signature (assembly, pb, error);
-       return_if_nok (error);
-
-
-       /* FIXME: we still don't handle 'other' methods */
-       if (pb->get_method) num_methods ++;
-       if (pb->set_method) num_methods ++;
-
-       table = &assembly->tables [MONO_TABLE_METHODSEMANTICS];
-       table->rows += num_methods;
-       alloc_table (table, table->rows);
-
-       if (pb->get_method) {
-               semaidx = table->next_idx ++;
-               values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
-               values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_GETTER;
-               values [MONO_METHOD_SEMA_METHOD] = pb->get_method->table_idx;
-               values [MONO_METHOD_SEMA_ASSOCIATION] = (pb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_PROPERTY;
-       }
-       if (pb->set_method) {
-               semaidx = table->next_idx ++;
-               values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
-               values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_SETTER;
-               values [MONO_METHOD_SEMA_METHOD] = pb->set_method->table_idx;
-               values [MONO_METHOD_SEMA_ASSOCIATION] = (pb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_PROPERTY;
+       if (*p == '"') {
+               quoted = TRUE;
+               p++;
        }
-       if (pb->attrs & PROPERTY_ATTRIBUTE_HAS_DEFAULT) {
-               MonoTypeEnum field_type = (MonoTypeEnum)0;
-               table = &assembly->tables [MONO_TABLE_CONSTANT];
-               table->rows ++;
-               alloc_table (table, table->rows);
-               values = table->values + table->rows * MONO_CONSTANT_SIZE;
-               values [MONO_CONSTANT_PARENT] = MONO_HASCONSTANT_PROPERTY | (pb->table_idx << MONO_HASCONSTANT_BITS);
-               values [MONO_CONSTANT_VALUE] = encode_constant (assembly, pb->def_value, &field_type);
-               values [MONO_CONSTANT_TYPE] = field_type;
-               values [MONO_CONSTANT_PADDING] = 0;
-       }
-}
-
-static void
-mono_image_get_event_info (MonoReflectionEventBuilder *eb, MonoDynamicImage *assembly, MonoError *error)
-{
-       MONO_REQ_GC_UNSAFE_MODE;
-
-       MonoDynamicTable *table;
-       guint32 *values;
-       guint num_methods = 0;
-       guint32 semaidx;
-
-       /* 
-        * we need to set things in the following tables:
-        * EVENTMAP (info already filled in _get_type_info ())
-        * EVENT    (rows already preallocated in _get_type_info ())
-        * METHOD      (method info already done with the generic method code)
-        * METHODSEMANTICS
-        */
-       table = &assembly->tables [MONO_TABLE_EVENT];
-       eb->table_idx = table->next_idx ++;
-       values = table->values + eb->table_idx * MONO_EVENT_SIZE;
-       values [MONO_EVENT_NAME] = string_heap_insert_mstring (&assembly->sheap, eb->name, error);
-       return_if_nok (error);
-       values [MONO_EVENT_FLAGS] = eb->attrs;
-       MonoType *ebtype = mono_reflection_type_get_handle (eb->type, error);
-       return_if_nok (error);
-       values [MONO_EVENT_TYPE] = mono_image_typedef_or_ref (assembly, ebtype);
-
-       /*
-        * FIXME: we still don't handle 'other' methods 
-        */
-       if (eb->add_method) num_methods ++;
-       if (eb->remove_method) num_methods ++;
-       if (eb->raise_method) num_methods ++;
-
-       table = &assembly->tables [MONO_TABLE_METHODSEMANTICS];
-       table->rows += num_methods;
-       alloc_table (table, table->rows);
-
-       if (eb->add_method) {
-               semaidx = table->next_idx ++;
-               values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
-               values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_ADD_ON;
-               values [MONO_METHOD_SEMA_METHOD] = eb->add_method->table_idx;
-               values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_EVENT;
-       }
-       if (eb->remove_method) {
-               semaidx = table->next_idx ++;
-               values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
-               values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_REMOVE_ON;
-               values [MONO_METHOD_SEMA_METHOD] = eb->remove_method->table_idx;
-               values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_EVENT;
-       }
-       if (eb->raise_method) {
-               semaidx = table->next_idx ++;
-               values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
-               values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_FIRE;
-               values [MONO_METHOD_SEMA_METHOD] = eb->raise_method->table_idx;
-               values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_EVENT;
-       }
-}
-
-static void
-encode_constraints (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly, MonoError *error)
-{
-       MONO_REQ_GC_UNSAFE_MODE;
-
-       mono_error_init (error);
-
-       MonoDynamicTable *table;
-       guint32 num_constraints, i;
-       guint32 *values;
-       guint32 table_idx;
-
-       table = &assembly->tables [MONO_TABLE_GENERICPARAMCONSTRAINT];
-       num_constraints = gparam->iface_constraints ?
-               mono_array_length (gparam->iface_constraints) : 0;
-       table->rows += num_constraints;
-       if (gparam->base_type)
-               table->rows++;
-       alloc_table (table, table->rows);
-
-       if (gparam->base_type) {
-               table_idx = table->next_idx ++;
-               values = table->values + table_idx * MONO_GENPARCONSTRAINT_SIZE;
-
-               MonoType *gpbasetype = mono_reflection_type_get_handle (gparam->base_type, error);
-               return_if_nok (error);
-               values [MONO_GENPARCONSTRAINT_GENERICPAR] = owner;
-               values [MONO_GENPARCONSTRAINT_CONSTRAINT] = mono_image_typedef_or_ref (assembly, gpbasetype);
-       }
-
-       for (i = 0; i < num_constraints; i++) {
-               MonoReflectionType *constraint = (MonoReflectionType *)mono_array_get (
-                       gparam->iface_constraints, gpointer, i);
-
-               table_idx = table->next_idx ++;
-               values = table->values + table_idx * MONO_GENPARCONSTRAINT_SIZE;
-
-               MonoType *constraint_type = mono_reflection_type_get_handle (constraint, error);
-               return_if_nok (error);
-
-               values [MONO_GENPARCONSTRAINT_GENERICPAR] = owner;
-               values [MONO_GENPARCONSTRAINT_CONSTRAINT] = mono_image_typedef_or_ref (assembly, constraint_type);
-       }
-}
-
-static void
-mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly)
-{
-       MONO_REQ_GC_UNSAFE_MODE;
-
-       GenericParamTableEntry *entry;
-
-       /*
-        * The GenericParam table must be sorted according to the `owner' field.
-        * We need to do this sorting prior to writing the GenericParamConstraint
-        * table, since we have to use the final GenericParam table indices there
-        * and they must also be sorted.
-        */
-
-       entry = g_new0 (GenericParamTableEntry, 1);
-       entry->owner = owner;
-       /* FIXME: track where gen_params should be freed and remove the GC root as well */
-       MONO_GC_REGISTER_ROOT_IF_MOVING (entry->gparam, MONO_ROOT_SOURCE_REFLECTION, "reflection generic parameter");
-       entry->gparam = gparam;
-       
-       g_ptr_array_add (assembly->gen_params, entry);
-}
-
-static gboolean
-write_generic_param_entry (MonoDynamicImage *assembly, GenericParamTableEntry *entry, MonoError *error)
-{
-       MONO_REQ_GC_UNSAFE_MODE;
-
-       MonoDynamicTable *table;
-       MonoGenericParam *param;
-       guint32 *values;
-       guint32 table_idx;
-
-       mono_error_init (error);
-
-       table = &assembly->tables [MONO_TABLE_GENERICPARAM];
-       table_idx = table->next_idx ++;
-       values = table->values + table_idx * MONO_GENERICPARAM_SIZE;
-
-       MonoType *gparam_type = mono_reflection_type_get_handle ((MonoReflectionType*)entry->gparam, error);
-       return_val_if_nok (error, FALSE);
-
-       param = gparam_type->data.generic_param;
-
-       values [MONO_GENERICPARAM_OWNER] = entry->owner;
-       values [MONO_GENERICPARAM_FLAGS] = entry->gparam->attrs;
-       values [MONO_GENERICPARAM_NUMBER] = mono_generic_param_num (param);
-       values [MONO_GENERICPARAM_NAME] = string_heap_insert (&assembly->sheap, mono_generic_param_info (param)->name);
-
-       if (!mono_image_add_cattrs (assembly, table_idx, MONO_CUSTOM_ATTR_GENERICPAR, entry->gparam->cattrs, error))
-               return FALSE;
-
-       encode_constraints (entry->gparam, table_idx, assembly, error);
-       return_val_if_nok (error, FALSE);
-
-       return TRUE;
-}
-
-static guint32
-resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
-{
-       MONO_REQ_GC_UNSAFE_MODE;
-
-       MonoDynamicTable *table;
-       guint32 token;
-       guint32 *values;
-       guint32 cols [MONO_ASSEMBLY_SIZE];
-       const char *pubkey;
-       guint32 publen;
-
-       if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, image))))
-               return token;
-
-       if (assembly_is_dynamic (image->assembly) && (image->assembly == assembly->image.assembly)) {
-               table = &assembly->tables [MONO_TABLE_MODULEREF];
-               token = table->next_idx ++;
-               table->rows ++;
-               alloc_table (table, table->rows);
-               values = table->values + token * MONO_MODULEREF_SIZE;
-               values [MONO_MODULEREF_NAME] = string_heap_insert (&assembly->sheap, image->module_name);
-
-               token <<= MONO_RESOLUTION_SCOPE_BITS;
-               token |= MONO_RESOLUTION_SCOPE_MODULEREF;
-               g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
-
-               return token;
-       }
-       
-       if (assembly_is_dynamic (image->assembly))
-               /* FIXME: */
-               memset (cols, 0, sizeof (cols));
-       else {
-               /* image->assembly->image is the manifest module */
-               image = image->assembly->image;
-               mono_metadata_decode_row (&image->tables [MONO_TABLE_ASSEMBLY], 0, cols, MONO_ASSEMBLY_SIZE);
-       }
-
-       table = &assembly->tables [MONO_TABLE_ASSEMBLYREF];
-       token = table->next_idx ++;
-       table->rows ++;
-       alloc_table (table, table->rows);
-       values = table->values + token * MONO_ASSEMBLYREF_SIZE;
-       values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, image->assembly_name);
-       values [MONO_ASSEMBLYREF_MAJOR_VERSION] = cols [MONO_ASSEMBLY_MAJOR_VERSION];
-       values [MONO_ASSEMBLYREF_MINOR_VERSION] = cols [MONO_ASSEMBLY_MINOR_VERSION];
-       values [MONO_ASSEMBLYREF_BUILD_NUMBER] = cols [MONO_ASSEMBLY_BUILD_NUMBER];
-       values [MONO_ASSEMBLYREF_REV_NUMBER] = cols [MONO_ASSEMBLY_REV_NUMBER];
-       values [MONO_ASSEMBLYREF_FLAGS] = 0;
-       values [MONO_ASSEMBLYREF_CULTURE] = 0;
-       values [MONO_ASSEMBLYREF_HASH_VALUE] = 0;
-
-       if (strcmp ("", image->assembly->aname.culture)) {
-               values [MONO_ASSEMBLYREF_CULTURE] = string_heap_insert (&assembly->sheap,
-                               image->assembly->aname.culture);
-       }
-
-       if ((pubkey = mono_image_get_public_key (image, &publen))) {
-               guchar pubtoken [9];
-               pubtoken [0] = 8;
-               mono_digest_get_public_token (pubtoken + 1, (guchar*)pubkey, publen);
-               values [MONO_ASSEMBLYREF_PUBLIC_KEY] = mono_image_add_stream_data (&assembly->blob, (char*)pubtoken, 9);
-       } else {
-               values [MONO_ASSEMBLYREF_PUBLIC_KEY] = 0;
-       }
-       token <<= MONO_RESOLUTION_SCOPE_BITS;
-       token |= MONO_RESOLUTION_SCOPE_ASSEMBLYREF;
-       g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
-       return token;
-}
-
-static guint32
-create_typespec (MonoDynamicImage *assembly, MonoType *type)
-{
-       MONO_REQ_GC_NEUTRAL_MODE;
-
-       MonoDynamicTable *table;
-       guint32 *values;
-       guint32 token;
-       SigBuffer buf;
-
-       if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typespec, type))))
-               return token;
-
-       sigbuffer_init (&buf, 32);
-       switch (type->type) {
-       case MONO_TYPE_FNPTR:
-       case MONO_TYPE_PTR:
-       case MONO_TYPE_SZARRAY:
-       case MONO_TYPE_ARRAY:
-       case MONO_TYPE_VAR:
-       case MONO_TYPE_MVAR:
-       case MONO_TYPE_GENERICINST:
-               encode_type (assembly, type, &buf);
-               break;
-       case MONO_TYPE_CLASS:
-       case MONO_TYPE_VALUETYPE: {
-               MonoClass *k = mono_class_from_mono_type (type);
-               if (!k || !k->generic_container) {
-                       sigbuffer_free (&buf);
-                       return 0;
-               }
-               encode_type (assembly, type, &buf);
-               break;
-       }
-       default:
-               sigbuffer_free (&buf);
-               return 0;
-       }
-
-       table = &assembly->tables [MONO_TABLE_TYPESPEC];
-       if (assembly->save) {
-               token = sigbuffer_add_to_blob_cached (assembly, &buf);
-               alloc_table (table, table->rows + 1);
-               values = table->values + table->next_idx * MONO_TYPESPEC_SIZE;
-               values [MONO_TYPESPEC_SIGNATURE] = token;
-       }
-       sigbuffer_free (&buf);
-
-       token = MONO_TYPEDEFORREF_TYPESPEC | (table->next_idx << MONO_TYPEDEFORREF_BITS);
-       g_hash_table_insert (assembly->typespec, type, GUINT_TO_POINTER(token));
-       table->next_idx ++;
-       return token;
-}
-
-static guint32
-mono_image_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType *type, gboolean try_typespec)
-{
-       MONO_REQ_GC_UNSAFE_MODE;
-
-       MonoDynamicTable *table;
-       guint32 *values;
-       guint32 token, scope, enclosing;
-       MonoClass *klass;
-
-       /* if the type requires a typespec, we must try that first*/
-       if (try_typespec && (token = create_typespec (assembly, type)))
-               return token;
-       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typeref, type));
-       if (token)
-               return token;
-       klass = mono_class_from_mono_type (type);
-       if (!klass)
-               klass = mono_class_from_mono_type (type);
-
-       /*
-        * If it's in the same module and not a generic type parameter:
-        */
-       if ((klass->image == &assembly->image) && (type->type != MONO_TYPE_VAR) && 
-                       (type->type != MONO_TYPE_MVAR)) {
-               MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
-               token = MONO_TYPEDEFORREF_TYPEDEF | (tb->table_idx << MONO_TYPEDEFORREF_BITS);
-               register_dyn_token (assembly, token, (MonoObject *)mono_class_get_ref_info (klass));
-               return token;
-       }
-
-       if (klass->nested_in) {
-               enclosing = mono_image_typedef_or_ref_full (assembly, &klass->nested_in->byval_arg, FALSE);
-               /* get the typeref idx of the enclosing type */
-               enclosing >>= MONO_TYPEDEFORREF_BITS;
-               scope = (enclosing << MONO_RESOLUTION_SCOPE_BITS) | MONO_RESOLUTION_SCOPE_TYPEREF;
-       } else {
-               scope = resolution_scope_from_image (assembly, klass->image);
-       }
-       table = &assembly->tables [MONO_TABLE_TYPEREF];
-       if (assembly->save) {
-               alloc_table (table, table->rows + 1);
-               values = table->values + table->next_idx * MONO_TYPEREF_SIZE;
-               values [MONO_TYPEREF_SCOPE] = scope;
-               values [MONO_TYPEREF_NAME] = string_heap_insert (&assembly->sheap, klass->name);
-               values [MONO_TYPEREF_NAMESPACE] = string_heap_insert (&assembly->sheap, klass->name_space);
-       }
-       token = MONO_TYPEDEFORREF_TYPEREF | (table->next_idx << MONO_TYPEDEFORREF_BITS); /* typeref */
-       g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token));
-       table->next_idx ++;
-       register_dyn_token (assembly, token, (MonoObject *)mono_class_get_ref_info (klass));
-       return token;
-}
-
-/*
- * Despite the name, we handle also TypeSpec (with the above helper).
- */
-static guint32
-mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
-{
-       return mono_image_typedef_or_ref_full (assembly, type, TRUE);
-}
-
-#ifndef DISABLE_REFLECTION_EMIT
-static guint32
-mono_image_add_memberef_row (MonoDynamicImage *assembly, guint32 parent, const char *name, guint32 sig)
-{
-       MONO_REQ_GC_NEUTRAL_MODE;
-
-       MonoDynamicTable *table;
-       guint32 *values;
-       guint32 token, pclass;
-
-       switch (parent & MONO_TYPEDEFORREF_MASK) {
-       case MONO_TYPEDEFORREF_TYPEREF:
-               pclass = MONO_MEMBERREF_PARENT_TYPEREF;
-               break;
-       case MONO_TYPEDEFORREF_TYPESPEC:
-               pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
-               break;
-       case MONO_TYPEDEFORREF_TYPEDEF:
-               pclass = MONO_MEMBERREF_PARENT_TYPEDEF;
-               break;
-       default:
-               g_warning ("unknown typeref or def token 0x%08x for %s", parent, name);
-               return 0;
-       }
-       /* extract the index */
-       parent >>= MONO_TYPEDEFORREF_BITS;
-
-       table = &assembly->tables [MONO_TABLE_MEMBERREF];
-
-       if (assembly->save) {
-               alloc_table (table, table->rows + 1);
-               values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
-               values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
-               values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
-               values [MONO_MEMBERREF_SIGNATURE] = sig;
-       }
-
-       token = MONO_TOKEN_MEMBER_REF | table->next_idx;
-       table->next_idx ++;
-
-       return token;
-}
-
-/*
- * Insert a memberef row into the metadata: the token that point to the memberref
- * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
- * mono_image_get_fieldref_token()).
- * The sig param is an index to an already built signature.
- */
-static guint32
-mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, const char *name, guint32 sig)
-{
-       MONO_REQ_GC_NEUTRAL_MODE;
-
-       guint32 parent = mono_image_typedef_or_ref (assembly, type);
-       return mono_image_add_memberef_row (assembly, parent, name, sig);
-}
-
-
-static guint32
-mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
-{
-       MONO_REQ_GC_NEUTRAL_MODE;
-
-       guint32 token;
-       MonoMethodSignature *sig;
-       
-       create_typespec = create_typespec && method->is_generic && method->klass->image != &assembly->image;
-
-       if (create_typespec) {
-               token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1)));
-               if (token)
-                       return token;
-       } 
-
-       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
-       if (token && !create_typespec)
-               return token;
-
-       g_assert (!method->is_inflated);
-       if (!token) {
-               /*
-                * A methodref signature can't contain an unmanaged calling convention.
-                */
-               sig = mono_metadata_signature_dup (mono_method_signature (method));
-               if ((sig->call_convention != MONO_CALL_DEFAULT) && (sig->call_convention != MONO_CALL_VARARG))
-                       sig->call_convention = MONO_CALL_DEFAULT;
-               token = mono_image_get_memberref_token (assembly, &method->klass->byval_arg,
-                       method->name,  method_encode_signature (assembly, sig));
-               g_free (sig);
-               g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
-       }
-
-       if (create_typespec) {
-               MonoDynamicTable *table = &assembly->tables [MONO_TABLE_METHODSPEC];
-               g_assert (mono_metadata_token_table (token) == MONO_TABLE_MEMBERREF);
-               token = (mono_metadata_token_index (token) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
-
-               if (assembly->save) {
-                       guint32 *values;
-
-                       alloc_table (table, table->rows + 1);
-                       values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
-                       values [MONO_METHODSPEC_METHOD] = token;
-                       values [MONO_METHODSPEC_SIGNATURE] = encode_generic_method_sig (assembly, &mono_method_get_generic_container (method)->context);
-               }
-
-               token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
-               table->next_idx ++;
-               /*methodspec and memberef tokens are diferent, */
-               g_hash_table_insert (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1), GUINT_TO_POINTER (token));
-               return token;
-       }
-       return token;
-}
-
-static guint32
-mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method, MonoError *error)
-{
-       guint32 token, parent, sig;
-       ReflectionMethodBuilder rmb;
-       MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)method->type;
-       
-       mono_error_init (error);
-       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
-       if (token)
-               return token;
-
-       if (!reflection_methodbuilder_from_method_builder (&rmb, method, error))
-               return 0;
-
-       /*
-        * A methodref signature can't contain an unmanaged calling convention.
-        * Since some flags are encoded as part of call_conv, we need to check against it.
-       */
-       if ((rmb.call_conv & ~0x60) != MONO_CALL_DEFAULT && (rmb.call_conv & ~0x60) != MONO_CALL_VARARG)
-               rmb.call_conv = (rmb.call_conv & 0x60) | MONO_CALL_DEFAULT;
-
-       sig = method_builder_encode_signature (assembly, &rmb, error);
-       return_val_if_nok (error, 0);
-
-       if (tb->generic_params) {
-               parent = create_generic_typespec (assembly, tb, error);
-               return_val_if_nok (error, 0);
-       } else {
-               MonoType *t = mono_reflection_type_get_handle ((MonoReflectionType*)rmb.type, error);
-               return_val_if_nok (error, 0);
-
-               parent = mono_image_typedef_or_ref (assembly, t);
-       }
-
-       char *name = mono_string_to_utf8_checked (method->name, error);
-       return_val_if_nok (error, 0);
-
-       token = mono_image_add_memberef_row (assembly, parent, name, sig);
-       g_free (name);
-
-       g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
-
-       return token;
-}
-
-static guint32
-mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 original,
-                                    const gchar *name, guint32 sig)
-{
-       MonoDynamicTable *table;
-       guint32 token;
-       guint32 *values;
-       
-       table = &assembly->tables [MONO_TABLE_MEMBERREF];
-
-       if (assembly->save) {
-               alloc_table (table, table->rows + 1);
-               values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
-               values [MONO_MEMBERREF_CLASS] = original;
-               values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
-               values [MONO_MEMBERREF_SIGNATURE] = sig;
-       }
-
-       token = MONO_TOKEN_MEMBER_REF | table->next_idx;
-       table->next_idx ++;
-
-       return token;
-}
-
-static guint32
-encode_generic_method_definition_sig (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb)
-{
-       SigBuffer buf;
-       int i;
-       guint32 nparams = mono_array_length (mb->generic_params);
-       guint32 idx;
-
-       if (!assembly->save)
-               return 0;
-
-       sigbuffer_init (&buf, 32);
-
-       sigbuffer_add_value (&buf, 0xa);
-       sigbuffer_add_value (&buf, nparams);
-
-       for (i = 0; i < nparams; i++) {
-               sigbuffer_add_value (&buf, MONO_TYPE_MVAR);
-               sigbuffer_add_value (&buf, i);
-       }
-
-       idx = sigbuffer_add_to_blob_cached (assembly, &buf);
-       sigbuffer_free (&buf);
-       return idx;
-}
-
-static guint32
-mono_image_get_methodspec_token_for_generic_method_definition (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, MonoError *error)
-{
-       MonoDynamicTable *table;
-       guint32 *values;
-       guint32 token, mtoken = 0;
-
-       mono_error_init (error);
-       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->methodspec, mb));
-       if (token)
-               return token;
-
-       table = &assembly->tables [MONO_TABLE_METHODSPEC];
-
-       mtoken = mono_image_get_methodref_token_for_methodbuilder (assembly, mb, error);
-       if (!mono_error_ok (error))
-               return 0;
-
-       switch (mono_metadata_token_table (mtoken)) {
-       case MONO_TABLE_MEMBERREF:
-               mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
-               break;
-       case MONO_TABLE_METHOD:
-               mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
-               break;
-       default:
-               g_assert_not_reached ();
-       }
-
-       if (assembly->save) {
-               alloc_table (table, table->rows + 1);
-               values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
-               values [MONO_METHODSPEC_METHOD] = mtoken;
-               values [MONO_METHODSPEC_SIGNATURE] = encode_generic_method_definition_sig (assembly, mb);
-       }
-
-       token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
-       table->next_idx ++;
-
-       mono_g_hash_table_insert (assembly->methodspec, mb, GUINT_TO_POINTER(token));
-       return token;
-}
-
-static guint32
-mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_methodspec, MonoError *error)
-{
-       guint32 token;
-
-       mono_error_init (error);
-
-       if (mb->generic_params && create_methodspec) 
-               return mono_image_get_methodspec_token_for_generic_method_definition (assembly, mb, error);
-
-       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, mb));
-       if (token)
-               return token;
-
-       token = mono_image_get_methodref_token_for_methodbuilder (assembly, mb, error);
-       if (!mono_error_ok (error))
-               return 0;
-       mono_g_hash_table_insert (assembly->handleref_managed, mb, GUINT_TO_POINTER(token));
-       return token;
-}
-
-static guint32
-mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtorBuilder *mb, MonoError *error)
-{
-       guint32 token, parent, sig;
-       ReflectionMethodBuilder rmb;
-       char *name;
-       MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mb->type;
-       
-       mono_error_init (error);
-       
-       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, mb));
-       if (token)
-               return token;
-
-       if (!reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
-               return 0;
-
-       if (tb->generic_params) {
-               parent = create_generic_typespec (assembly, tb, error);
-               return_val_if_nok (error, 0);
-       } else {
-               MonoType * type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
-               return_val_if_nok (error, 0);
-               parent = mono_image_typedef_or_ref (assembly, type);
-       }
-       
-       name = mono_string_to_utf8_checked (rmb.name, error);
-       return_val_if_nok (error, 0);
-       sig = method_builder_encode_signature (assembly, &rmb, error);
-       return_val_if_nok (error, 0);
-
-       token = mono_image_add_memberef_row (assembly, parent, name, sig);
-
-       g_free (name);
-       mono_g_hash_table_insert (assembly->handleref_managed, mb, GUINT_TO_POINTER(token));
-       return token;
-}
-#endif
-
-static gboolean
-is_field_on_inst (MonoClassField *field)
-{
-       return (field->parent->generic_class && field->parent->generic_class->is_dynamic && ((MonoDynamicGenericClass*)field->parent->generic_class)->fields);
-}
-
-/*
- * If FIELD is a field of a MonoDynamicGenericClass, return its non-inflated type.
- */
-static MonoType*
-get_field_on_inst_generic_type (MonoClassField *field)
-{
-       MonoClass *klass, *gtd;
-       MonoDynamicGenericClass *dgclass;
-       int field_index;
-
-       g_assert (is_field_on_inst (field));
-
-       dgclass = (MonoDynamicGenericClass*)field->parent->generic_class;
-
-       if (field >= dgclass->fields && field - dgclass->fields < dgclass->count_fields) {
-               field_index = field - dgclass->fields;
-               return dgclass->field_generic_types [field_index];              
-       }
-
-       klass = field->parent;
-       gtd = klass->generic_class->container_class;
-
-       if (field >= klass->fields && field - klass->fields < klass->field.count) {
-               field_index = field - klass->fields;
-               return gtd->fields [field_index].type;
-       }
-
-       g_assert_not_reached ();
-       return 0;
-}
-
-#ifndef DISABLE_REFLECTION_EMIT
-static guint32
-mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObject *f, MonoClassField *field)
-{
-       MonoType *type;
-       guint32 token;
-
-       g_assert (field);
-       g_assert (field->parent);
-
-       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
-       if (token)
-               return token;
-
-       if (field->parent->generic_class && field->parent->generic_class->container_class && field->parent->generic_class->container_class->fields) {
-               int index = field - field->parent->fields;
-               type = mono_field_get_type (&field->parent->generic_class->container_class->fields [index]);
-       } else {
-               if (is_field_on_inst (field))
-                       type = get_field_on_inst_generic_type (field);
-               else
-                       type = mono_field_get_type (field);
-       }
-       token = mono_image_get_memberref_token (assembly, &field->parent->byval_arg,
-                                                                                       mono_field_get_name (field),
-                                                                                       fieldref_encode_signature (assembly, field->parent->image, type));
-       mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER(token));
-       return token;
-}
-
-static guint32
-mono_image_get_field_on_inst_token (MonoDynamicImage *assembly, MonoReflectionFieldOnTypeBuilderInst *f, MonoError *error)
-{
-       guint32 token;
-       MonoClass *klass;
-       MonoGenericClass *gclass;
-       MonoType *type;
-       char *name;
-
-       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
-       if (token)
-               return token;
-       if (is_sre_field_builder (mono_object_class (f->fb))) {
-               MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)f->fb;
-               type = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst, error);
-               return_val_if_nok (error, 0);
-               klass = mono_class_from_mono_type (type);
-               gclass = type->data.generic_class;
-               g_assert (gclass->is_dynamic);
-
-               guint32 sig_token = field_encode_signature (assembly, fb, error);
-               return_val_if_nok (error, 0);
-               name = mono_string_to_utf8_checked (fb->name, error);
-               return_val_if_nok (error, 0);
-               token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig_token);
-               g_free (name);          
-       } else if (is_sr_mono_field (mono_object_class (f->fb))) {
-               guint32 sig;
-               MonoClassField *field = ((MonoReflectionField *)f->fb)->field;
-
-               type = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst, error);
-               return_val_if_nok (error, 0);
-               klass = mono_class_from_mono_type (type);
-
-               sig = fieldref_encode_signature (assembly, field->parent->image, field->type);
-               token = mono_image_get_memberref_token (assembly, &klass->byval_arg, field->name, sig);
-       } else {
-               char *name = mono_type_get_full_name (mono_object_class (f->fb));
-               g_error ("mono_image_get_field_on_inst_token: don't know how to handle %s", name);
-       }
-
-       mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER (token));
-       return token;
-}
-
-static guint32
-mono_image_get_ctor_on_inst_token (MonoDynamicImage *assembly, MonoReflectionCtorOnTypeBuilderInst *c, gboolean create_methodspec, MonoError *error)
-{
-       guint32 sig, token;
-       MonoClass *klass;
-       MonoGenericClass *gclass;
-       MonoType *type;
-
-       mono_error_init (error);
-
-       /* A ctor cannot be a generic method, so we can ignore create_methodspec */
-
-       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, c));
-       if (token)
-               return token;
-
-       if (is_sre_ctor_builder (mono_object_class (c->cb))) {
-               MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder *)c->cb;
-               ReflectionMethodBuilder rmb;
-               char *name;
-
-               type = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst, error);
-               return_val_if_nok (error, 0);
-               klass = mono_class_from_mono_type (type);
-
-               gclass = type->data.generic_class;
-               g_assert (gclass->is_dynamic);
-
-               if (!reflection_methodbuilder_from_ctor_builder (&rmb, cb, error))
-                       return 0;
-
-               sig = method_builder_encode_signature (assembly, &rmb, error);
-               return_val_if_nok (error, 0);
-
-               name = mono_string_to_utf8_checked (rmb.name, error);
-               return_val_if_nok (error, 0);
-
-               token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
-               g_free (name);
-       } else if (is_sr_mono_cmethod (mono_object_class (c->cb))) {
-               MonoMethod *mm = ((MonoReflectionMethod *)c->cb)->method;
-
-               type = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst, error);
-               return_val_if_nok (error, 0);
-               klass = mono_class_from_mono_type (type);
-
-               sig = method_encode_signature (assembly, mono_method_signature (mm));
-               token = mono_image_get_memberref_token (assembly, &klass->byval_arg, mm->name, sig);
-       } else {
-               char *name = mono_type_get_full_name (mono_object_class (c->cb));
-               g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
-       }
-
-
-       mono_g_hash_table_insert (assembly->handleref_managed, c, GUINT_TO_POINTER (token));
-       return token;
-}
-
-static MonoMethod*
-mono_reflection_method_on_tb_inst_get_handle (MonoReflectionMethodOnTypeBuilderInst *m, MonoError *error)
-{
-       MonoClass *klass;
-       MonoGenericContext tmp_context;
-       MonoType **type_argv;
-       MonoGenericInst *ginst;
-       MonoMethod *method, *inflated;
-       int count, i;
-
-       mono_error_init (error);
-
-       init_type_builder_generics ((MonoObject*)m->inst, error);
-       return_val_if_nok (error, NULL);
-
-       method = inflate_method (m->inst, (MonoObject*)m->mb, error);
-       return_val_if_nok (error, NULL);
-
-       klass = method->klass;
-
-       if (m->method_args == NULL)
-               return method;
-
-       if (method->is_inflated)
-               method = ((MonoMethodInflated *) method)->declaring;
-
-       count = mono_array_length (m->method_args);
-
-       type_argv = g_new0 (MonoType *, count);
-       for (i = 0; i < count; i++) {
-               MonoReflectionType *garg = (MonoReflectionType *)mono_array_get (m->method_args, gpointer, i);
-               type_argv [i] = mono_reflection_type_get_handle (garg, error);
-               return_val_if_nok (error, NULL);
-       }
-       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.method_inst = ginst;
-
-       inflated = mono_class_inflate_generic_method_checked (method, &tmp_context, error);
-       mono_error_assert_ok (error);
-       return inflated;
-}
-
-static guint32
-mono_image_get_method_on_inst_token (MonoDynamicImage *assembly, MonoReflectionMethodOnTypeBuilderInst *m, gboolean create_methodspec, MonoError *error)
-{
-       guint32 sig, token = 0;
-       MonoType *type;
-       MonoClass *klass;
-
-       mono_error_init (error);
-
-       if (m->method_args) {
-               MonoMethod *inflated;
-
-               inflated = mono_reflection_method_on_tb_inst_get_handle (m, error);
-               return_val_if_nok (error, 0);
-
-               if (create_methodspec)
-                       token = mono_image_get_methodspec_token (assembly, inflated);
-               else
-                       token = mono_image_get_inflated_method_token (assembly, inflated);
-               return token;
-       }
-
-       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, m));
-       if (token)
-               return token;
-
-       if (is_sre_method_builder (mono_object_class (m->mb))) {
-               MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)m->mb;
-               MonoGenericClass *gclass;
-               ReflectionMethodBuilder rmb;
-               char *name;
-
-               type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
-               return_val_if_nok (error, 0);
-               klass = mono_class_from_mono_type (type);
-               gclass = type->data.generic_class;
-               g_assert (gclass->is_dynamic);
-
-               if (!reflection_methodbuilder_from_method_builder (&rmb, mb, error))
-                       return 0;
-
-               sig = method_builder_encode_signature (assembly, &rmb, error);
-               return_val_if_nok (error, 0);
-
-               name = mono_string_to_utf8_checked (rmb.name, error);
-               return_val_if_nok (error, 0);
-
-               token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
-               g_free (name);          
-       } else if (is_sr_mono_method (mono_object_class (m->mb))) {
-               MonoMethod *mm = ((MonoReflectionMethod *)m->mb)->method;
-
-               type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
-               return_val_if_nok (error, 0);
-               klass = mono_class_from_mono_type (type);
-
-               sig = method_encode_signature (assembly, mono_method_signature (mm));
-               token = mono_image_get_memberref_token (assembly, &klass->byval_arg, mm->name, sig);
-       } else {
-               char *name = mono_type_get_full_name (mono_object_class (m->mb));
-               g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
-       }
-
-       mono_g_hash_table_insert (assembly->handleref_managed, m, GUINT_TO_POINTER (token));
-       return token;
-}
-
-static guint32
-encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericContext *context)
-{
-       SigBuffer buf;
-       int i;
-       guint32 nparams = context->method_inst->type_argc;
-       guint32 idx;
-
-       if (!assembly->save)
-               return 0;
-
-       sigbuffer_init (&buf, 32);
-       /*
-        * FIXME: vararg, explicit_this, differenc call_conv values...
-        */
-       sigbuffer_add_value (&buf, 0xa); /* FIXME FIXME FIXME */
-       sigbuffer_add_value (&buf, nparams);
-
-       for (i = 0; i < nparams; i++)
-               encode_type (assembly, context->method_inst->type_argv [i], &buf);
-
-       idx = sigbuffer_add_to_blob_cached (assembly, &buf);
-       sigbuffer_free (&buf);
-       return idx;
-}
-
-static guint32
-method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
-{
-       MonoDynamicTable *table;
-       guint32 *values;
-       guint32 token, mtoken = 0, sig;
-       MonoMethodInflated *imethod;
-       MonoMethod *declaring;
-
-       table = &assembly->tables [MONO_TABLE_METHODSPEC];
-
-       g_assert (method->is_inflated);
-       imethod = (MonoMethodInflated *) method;
-       declaring = imethod->declaring;
-
-       sig = method_encode_signature (assembly, mono_method_signature (declaring));
-       mtoken = mono_image_get_memberref_token (assembly, &method->klass->byval_arg, declaring->name, sig);
-
-       if (!mono_method_signature (declaring)->generic_param_count)
-               return mtoken;
-
-       switch (mono_metadata_token_table (mtoken)) {
-       case MONO_TABLE_MEMBERREF:
-               mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
-               break;
-       case MONO_TABLE_METHOD:
-               mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
-               break;
-       default:
-               g_assert_not_reached ();
-       }
-
-       sig = encode_generic_method_sig (assembly, mono_method_get_context (method));
-
-       if (assembly->save) {
-               alloc_table (table, table->rows + 1);
-               values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
-               values [MONO_METHODSPEC_METHOD] = mtoken;
-               values [MONO_METHODSPEC_SIGNATURE] = sig;
-       }
-
-       token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
-       table->next_idx ++;
-
-       return token;
-}
-
-static guint32
-mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method)
-{
-       MonoMethodInflated *imethod;
-       guint32 token;
-       
-       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
-       if (token)
-               return token;
-
-       g_assert (method->is_inflated);
-       imethod = (MonoMethodInflated *) method;
-
-       if (mono_method_signature (imethod->declaring)->generic_param_count) {
-               token = method_encode_methodspec (assembly, method);
-       } else {
-               guint32 sig = method_encode_signature (
-                       assembly, mono_method_signature (imethod->declaring));
-               token = mono_image_get_memberref_token (
-                       assembly, &method->klass->byval_arg, method->name, sig);
-       }
-
-       g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
-       return token;
-}
-
-static guint32
-mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m)
-{
-       MonoMethodInflated *imethod = (MonoMethodInflated *) m;
-       guint32 sig, token;
-
-       sig = method_encode_signature (assembly, mono_method_signature (imethod->declaring));
-       token = mono_image_get_memberref_token (
-               assembly, &m->klass->byval_arg, m->name, sig);
-
-       return token;
-}
-
-static guint32
-create_generic_typespec (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *tb, MonoError *error)
-{
-       MonoDynamicTable *table;
-       MonoClass *klass;
-       MonoType *type;
-       guint32 *values;
-       guint32 token;
-       SigBuffer buf;
-       int count, i;
-
-       /*
-        * We're creating a TypeSpec for the TypeBuilder of a generic type declaration,
-        * ie. what we'd normally use as the generic type in a TypeSpec signature.
-        * Because of this, we must not insert it into the `typeref' hash table.
-        */
-       type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
-       return_val_if_nok (error, 0);
-       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typespec, type));
-       if (token)
-               return token;
-
-       sigbuffer_init (&buf, 32);
-
-       g_assert (tb->generic_params);
-       klass = mono_class_from_mono_type (type);
-
-       if (tb->generic_container) {
-               if (!mono_reflection_create_generic_class (tb, error))
-                       goto fail;
-       }
-
-       sigbuffer_add_value (&buf, MONO_TYPE_GENERICINST);
-       g_assert (klass->generic_container);
-       sigbuffer_add_value (&buf, klass->byval_arg.type);
-       sigbuffer_add_value (&buf, mono_image_typedef_or_ref_full (assembly, &klass->byval_arg, FALSE));
-
-       count = mono_array_length (tb->generic_params);
-       sigbuffer_add_value (&buf, count);
-       for (i = 0; i < count; i++) {
-               MonoReflectionGenericParam *gparam;
-
-               gparam = mono_array_get (tb->generic_params, MonoReflectionGenericParam *, i);
-               MonoType *gparam_type = mono_reflection_type_get_handle ((MonoReflectionType*)gparam, error);
-               if (!is_ok (error))
-                       goto fail;
-
-               encode_type (assembly, gparam_type, &buf);
-       }
-
-       table = &assembly->tables [MONO_TABLE_TYPESPEC];
-
-       if (assembly->save) {
-               token = sigbuffer_add_to_blob_cached (assembly, &buf);
-               alloc_table (table, table->rows + 1);
-               values = table->values + table->next_idx * MONO_TYPESPEC_SIZE;
-               values [MONO_TYPESPEC_SIGNATURE] = token;
-       }
-       sigbuffer_free (&buf);
-
-       token = MONO_TYPEDEFORREF_TYPESPEC | (table->next_idx << MONO_TYPEDEFORREF_BITS);
-       g_hash_table_insert (assembly->typespec, type, GUINT_TO_POINTER(token));
-       table->next_idx ++;
-       return token;
-fail:
-       sigbuffer_free (&buf);
-       return 0;
-}
-
-/*
- * Return a copy of TYPE, adding the custom modifiers in MODREQ and MODOPT.
- */
-static MonoType*
-add_custom_modifiers (MonoDynamicImage *assembly, MonoType *type, MonoArray *modreq, MonoArray *modopt, MonoError *error)
-{
-       int i, count, len, pos;
-       MonoType *t;
-
-       mono_error_init (error);
-
-       count = 0;
-       if (modreq)
-               count += mono_array_length (modreq);
-       if (modopt)
-               count += mono_array_length (modopt);
-
-       if (count == 0)
-               return mono_metadata_type_dup (NULL, type);
-
-       len = MONO_SIZEOF_TYPE + ((gint32)count) * sizeof (MonoCustomMod);
-       t = (MonoType *)g_malloc (len);
-       memcpy (t, type, MONO_SIZEOF_TYPE);
-
-       t->num_mods = count;
-       pos = 0;
-       if (modreq) {
-               for (i = 0; i < mono_array_length (modreq); ++i) {
-                       MonoType *mod = mono_type_array_get_and_resolve (modreq, i, error);
-                       if (!is_ok (error))
-                               goto fail;
-                       t->modifiers [pos].required = 1;
-                       t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod);
-                       pos ++;
-               }
-       }
-       if (modopt) {
-               for (i = 0; i < mono_array_length (modopt); ++i) {
-                       MonoType *mod = mono_type_array_get_and_resolve (modopt, i, error);
-                       if (!is_ok (error))
-                               goto fail;
-                       t->modifiers [pos].required = 0;
-                       t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod);
-                       pos ++;
-               }
-       }
-
-       return t;
-fail:
-       g_free (t);
-       return NULL;
-}
-
-static void
-init_type_builder_generics (MonoObject *type, MonoError *error)
-{
-       MonoReflectionTypeBuilder *tb;
-
-       mono_error_init (error);
-
-       if (!is_sre_type_builder(mono_object_class (type)))
-               return;
-       tb = (MonoReflectionTypeBuilder *)type;
-
-       if (tb && tb->generic_container)
-               mono_reflection_create_generic_class (tb, error);
-}
-
-static guint32
-mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb, MonoError *error)
-{
-       MonoDynamicTable *table;
-       MonoType *custom = NULL, *type;
-       guint32 *values;
-       guint32 token, pclass, parent, sig;
-       gchar *name;
-
-       mono_error_init (error);
-
-       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, fb));
-       if (token)
-               return token;
-
-       MonoType *typeb = mono_reflection_type_get_handle (fb->typeb, error);
-       return_val_if_nok (error, 0);
-       /* FIXME: is this call necessary? */
-       mono_class_from_mono_type (typeb);
-
-       /*FIXME this is one more layer of ugliness due how types are created.*/
-       init_type_builder_generics (fb->type, error);
-       return_val_if_nok (error, 0);
-
-       /* fb->type does not include the custom modifiers */
-       /* FIXME: We should do this in one place when a fieldbuilder is created */
-       type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
-       return_val_if_nok (error, 0);
-
-       if (fb->modreq || fb->modopt) {
-               type = custom = add_custom_modifiers (assembly, type, fb->modreq, fb->modopt, error);
-               return_val_if_nok (error, 0);
-       }
-
-       sig = fieldref_encode_signature (assembly, NULL, type);
-       g_free (custom);
-
-       parent = create_generic_typespec (assembly, (MonoReflectionTypeBuilder *) fb->typeb, error);
-       return_val_if_nok (error, 0);
-       g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_TYPEDEFORREF_TYPESPEC);
-       
-       pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
-       parent >>= MONO_TYPEDEFORREF_BITS;
-
-       table = &assembly->tables [MONO_TABLE_MEMBERREF];
-
-       name = mono_string_to_utf8_checked (fb->name, error);
-       return_val_if_nok (error, 0);
-
-       if (assembly->save) {
-               alloc_table (table, table->rows + 1);
-               values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
-               values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
-               values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
-               values [MONO_MEMBERREF_SIGNATURE] = sig;
-       }
-
-       token = MONO_TOKEN_MEMBER_REF | table->next_idx;
-       table->next_idx ++;
-       mono_g_hash_table_insert (assembly->handleref_managed, fb, GUINT_TO_POINTER(token));
-       g_free (name);
-       return token;
-}
-
-static guint32
-mono_reflection_encode_sighelper (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error)
-{
-       SigBuffer buf;
-       guint32 nargs;
-       guint32 i, idx;
-
-       mono_error_init (error);
-
-       if (!assembly->save)
-               return 0;
-
-       /* FIXME: this means SignatureHelper.SignatureHelpType.HELPER_METHOD */
-       g_assert (helper->type == 2);
-
-       if (helper->arguments)
-               nargs = mono_array_length (helper->arguments);
-       else
-               nargs = 0;
-
-       sigbuffer_init (&buf, 32);
-
-       /* Encode calling convention */
-       /* Change Any to Standard */
-       if ((helper->call_conv & 0x03) == 0x03)
-               helper->call_conv = 0x01;
-       /* explicit_this implies has_this */
-       if (helper->call_conv & 0x40)
-               helper->call_conv &= 0x20;
-
-       if (helper->call_conv == 0) { /* Unmanaged */
-               idx = helper->unmanaged_call_conv - 1;
-       } else {
-               /* Managed */
-               idx = helper->call_conv & 0x60; /* has_this + explicit_this */
-               if (helper->call_conv & 0x02) /* varargs */
-                       idx += 0x05;
-       }
-
-       sigbuffer_add_byte (&buf, idx);
-       sigbuffer_add_value (&buf, nargs);
-       encode_reflection_type (assembly, helper->return_type, &buf, error);
-       if (!is_ok (error))
-               goto fail;
-       for (i = 0; i < nargs; ++i) {
-               MonoArray *modreqs = NULL;
-               MonoArray *modopts = NULL;
-               MonoReflectionType *pt;
-
-               if (helper->modreqs && (i < mono_array_length (helper->modreqs)))
-                       modreqs = mono_array_get (helper->modreqs, MonoArray*, i);
-               if (helper->modopts && (i < mono_array_length (helper->modopts)))
-                       modopts = mono_array_get (helper->modopts, MonoArray*, i);
-
-               encode_custom_modifiers (assembly, modreqs, modopts, &buf, error);
-               if (!is_ok (error))
-                       goto fail;
-               pt = mono_array_get (helper->arguments, MonoReflectionType*, i);
-               encode_reflection_type (assembly, pt, &buf, error);
-               if (!is_ok (error))
-                       goto fail;
-       }
-       idx = sigbuffer_add_to_blob_cached (assembly, &buf);
-       sigbuffer_free (&buf);
-
-       return idx;
-fail:
-       sigbuffer_free (&buf);
-       return 0;
-}
-
-static guint32 
-mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error)
-{
-       guint32 idx;
-       MonoDynamicTable *table;
-       guint32 *values;
-
-       mono_error_init (error);
-
-       table = &assembly->tables [MONO_TABLE_STANDALONESIG];
-       idx = table->next_idx ++;
-       table->rows ++;
-       alloc_table (table, table->rows);
-       values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
-
-       values [MONO_STAND_ALONE_SIGNATURE] =
-               mono_reflection_encode_sighelper (assembly, helper, error);
-       return_val_if_nok (error, 0);
-       
-       return idx;
-}
-
-static int
-reflection_cc_to_file (int call_conv) {
-       switch (call_conv & 0x3) {
-       case 0:
-       case 1: return MONO_CALL_DEFAULT;
-       case 2: return MONO_CALL_VARARG;
-       default:
-               g_assert_not_reached ();
-       }
-       return 0;
-}
-#endif /* !DISABLE_REFLECTION_EMIT */
-
-typedef struct {
-       MonoType *parent;
-       MonoMethodSignature *sig;
-       char *name;
-       guint32 token;
-} ArrayMethod;
-
-#ifndef DISABLE_REFLECTION_EMIT
-static guint32
-mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMethod *m, MonoError *error)
-{
-       guint32 nparams, i;
-       GList *tmp;
-       char *name = NULL;
-       MonoMethodSignature *sig;
-       ArrayMethod *am = NULL;
-       MonoType *mtype;
-
-       mono_error_init (error);
-
-       nparams = mono_array_length (m->parameters);
-       sig = (MonoMethodSignature *)g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * nparams);
-       sig->hasthis = 1;
-       sig->sentinelpos = -1;
-       sig->call_convention = reflection_cc_to_file (m->call_conv);
-       sig->param_count = nparams;
-       if (m->ret) {
-               sig->ret = mono_reflection_type_get_handle (m->ret, error);
-               if (!is_ok (error))
-                       goto fail;
-       } else
-               sig->ret = &mono_defaults.void_class->byval_arg;
-
-       mtype = mono_reflection_type_get_handle (m->parent, error);
-       if (!is_ok (error))
-               goto fail;
-
-       for (i = 0; i < nparams; ++i) {
-               sig->params [i] = mono_type_array_get_and_resolve (m->parameters, i, error);
-               if (!is_ok (error))
-                       goto fail;
-       }
-
-       name = mono_string_to_utf8_checked (m->name, error);
-       if (!is_ok (error))
-               goto fail;
-       for (tmp = assembly->array_methods; tmp; tmp = tmp->next) {
-               am = (ArrayMethod *)tmp->data;
-               if (strcmp (name, am->name) == 0 && 
-                               mono_metadata_type_equal (am->parent, mtype) &&
-                               mono_metadata_signature_equal (am->sig, sig)) {
-                       g_free (name);
-                       g_free (sig);
-                       m->table_idx = am->token & 0xffffff;
-                       return am->token;
-               }
-       }
-       am = g_new0 (ArrayMethod, 1);
-       am->name = name;
-       am->sig = sig;
-       am->parent = mtype;
-       am->token = mono_image_get_memberref_token (assembly, am->parent, name,
-               method_encode_signature (assembly, sig));
-       assembly->array_methods = g_list_prepend (assembly->array_methods, am);
-       m->table_idx = am->token & 0xffffff;
-       return am->token;
-fail:
-       g_free (am);
-       g_free (name);
-       g_free (sig);
-       return 0;
-
-}
-
-/*
- * Insert into the metadata tables all the info about the TypeBuilder tb.
- * Data in the tables is inserted in a predefined order, since some tables need to be sorted.
- */
-static gboolean
-mono_image_get_type_info (MonoDomain *domain, MonoReflectionTypeBuilder *tb, MonoDynamicImage *assembly, MonoError *error)
-{
-       MonoDynamicTable *table;
-       guint *values;
-       int i, is_object = 0, is_system = 0;
-       char *n;
-
-       mono_error_init (error);
-
-       table = &assembly->tables [MONO_TABLE_TYPEDEF];
-       values = table->values + tb->table_idx * MONO_TYPEDEF_SIZE;
-       values [MONO_TYPEDEF_FLAGS] = tb->attrs;
-       n = mono_string_to_utf8_checked (tb->name, error);
-       return_val_if_nok (error, FALSE);
-       if (strcmp (n, "Object") == 0)
-               is_object++;
-       values [MONO_TYPEDEF_NAME] = string_heap_insert (&assembly->sheap, n);
-       g_free (n);
-       n = mono_string_to_utf8_checked (tb->nspace, error);
-       return_val_if_nok (error, FALSE);
-       if (strcmp (n, "System") == 0)
-               is_system++;
-       values [MONO_TYPEDEF_NAMESPACE] = string_heap_insert (&assembly->sheap, n);
-       g_free (n);
-       if (tb->parent && !(is_system && is_object) && 
-                       !(tb->attrs & TYPE_ATTRIBUTE_INTERFACE)) { /* interfaces don't have a parent */
-               MonoType *parent_type = mono_reflection_type_get_handle ((MonoReflectionType*)tb->parent, error);
-               return_val_if_nok (error, FALSE);
-               values [MONO_TYPEDEF_EXTENDS] = mono_image_typedef_or_ref (assembly, parent_type);
-       } else {
-               values [MONO_TYPEDEF_EXTENDS] = 0;
-       }
-       values [MONO_TYPEDEF_FIELD_LIST] = assembly->tables [MONO_TABLE_FIELD].next_idx;
-       values [MONO_TYPEDEF_METHOD_LIST] = assembly->tables [MONO_TABLE_METHOD].next_idx;
-
-       /*
-        * if we have explicitlayout or sequentiallayouts, output data in the
-        * ClassLayout table.
-        */
-       if (((tb->attrs & TYPE_ATTRIBUTE_LAYOUT_MASK) != TYPE_ATTRIBUTE_AUTO_LAYOUT) &&
-                       ((tb->class_size > 0) || (tb->packing_size > 0))) {
-               table = &assembly->tables [MONO_TABLE_CLASSLAYOUT];
-               table->rows++;
-               alloc_table (table, table->rows);
-               values = table->values + table->rows * MONO_CLASS_LAYOUT_SIZE;
-               values [MONO_CLASS_LAYOUT_PARENT] = tb->table_idx;
-               values [MONO_CLASS_LAYOUT_CLASS_SIZE] = tb->class_size;
-               values [MONO_CLASS_LAYOUT_PACKING_SIZE] = tb->packing_size;
-       }
-
-       /* handle interfaces */
-       if (tb->interfaces) {
-               table = &assembly->tables [MONO_TABLE_INTERFACEIMPL];
-               i = table->rows;
-               table->rows += mono_array_length (tb->interfaces);
-               alloc_table (table, table->rows);
-               values = table->values + (i + 1) * MONO_INTERFACEIMPL_SIZE;
-               for (i = 0; i < mono_array_length (tb->interfaces); ++i) {
-                       MonoReflectionType* iface = (MonoReflectionType*) mono_array_get (tb->interfaces, gpointer, i);
-                       MonoType *iface_type = mono_reflection_type_get_handle (iface, error);
-                       return_val_if_nok (error, FALSE);
-                       values [MONO_INTERFACEIMPL_CLASS] = tb->table_idx;
-                       values [MONO_INTERFACEIMPL_INTERFACE] = mono_image_typedef_or_ref (assembly, iface_type);
-                       values += MONO_INTERFACEIMPL_SIZE;
-               }
-       }
-
-       /* handle fields */
-       if (tb->fields) {
-               table = &assembly->tables [MONO_TABLE_FIELD];
-               table->rows += tb->num_fields;
-               alloc_table (table, table->rows);
-               for (i = 0; i < tb->num_fields; ++i) {
-                       mono_image_get_field_info (
-                               mono_array_get (tb->fields, MonoReflectionFieldBuilder*, i), assembly, error);
-                       return_val_if_nok (error, FALSE);
-               }
-       }
-
-       /* handle constructors */
-       if (tb->ctors) {
-               table = &assembly->tables [MONO_TABLE_METHOD];
-               table->rows += mono_array_length (tb->ctors);
-               alloc_table (table, table->rows);
-               for (i = 0; i < mono_array_length (tb->ctors); ++i) {
-                       if (!mono_image_get_ctor_info (domain,
-                                                      mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i),
-                                                      assembly, error))
-                               return FALSE;
-               }
-       }
-
-       /* handle methods */
-       if (tb->methods) {
-               table = &assembly->tables [MONO_TABLE_METHOD];
-               table->rows += tb->num_methods;
-               alloc_table (table, table->rows);
-               for (i = 0; i < tb->num_methods; ++i) {
-                       if (!mono_image_get_method_info (
-                                   mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), assembly, error))
-                               return FALSE;
-               }
-       }
-
-       /* Do the same with properties etc.. */
-       if (tb->events && mono_array_length (tb->events)) {
-               table = &assembly->tables [MONO_TABLE_EVENT];
-               table->rows += mono_array_length (tb->events);
-               alloc_table (table, table->rows);
-               table = &assembly->tables [MONO_TABLE_EVENTMAP];
-               table->rows ++;
-               alloc_table (table, table->rows);
-               values = table->values + table->rows * MONO_EVENT_MAP_SIZE;
-               values [MONO_EVENT_MAP_PARENT] = tb->table_idx;
-               values [MONO_EVENT_MAP_EVENTLIST] = assembly->tables [MONO_TABLE_EVENT].next_idx;
-               for (i = 0; i < mono_array_length (tb->events); ++i) {
-                       mono_image_get_event_info (
-                               mono_array_get (tb->events, MonoReflectionEventBuilder*, i), assembly, error);
-                       return_val_if_nok (error, FALSE);
-               }
-       }
-       if (tb->properties && mono_array_length (tb->properties)) {
-               table = &assembly->tables [MONO_TABLE_PROPERTY];
-               table->rows += mono_array_length (tb->properties);
-               alloc_table (table, table->rows);
-               table = &assembly->tables [MONO_TABLE_PROPERTYMAP];
-               table->rows ++;
-               alloc_table (table, table->rows);
-               values = table->values + table->rows * MONO_PROPERTY_MAP_SIZE;
-               values [MONO_PROPERTY_MAP_PARENT] = tb->table_idx;
-               values [MONO_PROPERTY_MAP_PROPERTY_LIST] = assembly->tables [MONO_TABLE_PROPERTY].next_idx;
-               for (i = 0; i < mono_array_length (tb->properties); ++i) {
-                       mono_image_get_property_info (
-                               mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i), assembly, error);
-                       return_val_if_nok (error, FALSE);
-               }
-       }
-
-       /* handle generic parameters */
-       if (tb->generic_params) {
-               table = &assembly->tables [MONO_TABLE_GENERICPARAM];
-               table->rows += mono_array_length (tb->generic_params);
-               alloc_table (table, table->rows);
-               for (i = 0; i < mono_array_length (tb->generic_params); ++i) {
-                       guint32 owner = MONO_TYPEORMETHOD_TYPE | (tb->table_idx << MONO_TYPEORMETHOD_BITS);
-
-                       mono_image_get_generic_param_info (
-                               mono_array_get (tb->generic_params, MonoReflectionGenericParam*, i), owner, assembly);
-               }
-       }
-
-       mono_image_add_decl_security (assembly, 
-               mono_metadata_make_token (MONO_TABLE_TYPEDEF, tb->table_idx), tb->permissions);
-
-       if (tb->subtypes) {
-               MonoDynamicTable *ntable;
-               
-               ntable = &assembly->tables [MONO_TABLE_NESTEDCLASS];
-               ntable->rows += mono_array_length (tb->subtypes);
-               alloc_table (ntable, ntable->rows);
-               values = ntable->values + ntable->next_idx * MONO_NESTED_CLASS_SIZE;
-
-               for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
-                       MonoReflectionTypeBuilder *subtype = mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i);
-
-                       values [MONO_NESTED_CLASS_NESTED] = subtype->table_idx;
-                       values [MONO_NESTED_CLASS_ENCLOSING] = tb->table_idx;
-                       /*g_print ("nesting %s (%d) in %s (%d) (rows %d/%d)\n",
-                               mono_string_to_utf8 (subtype->name), subtype->table_idx,
-                               mono_string_to_utf8 (tb->name), tb->table_idx,
-                               ntable->next_idx, ntable->rows);*/
-                       values += MONO_NESTED_CLASS_SIZE;
-                       ntable->next_idx++;
-               }
-       }
-
-       return TRUE;
-}
-#endif
-
-static void
-collect_types (MonoPtrArray *types, MonoReflectionTypeBuilder *type)
-{
-       int i;
-
-       mono_ptr_array_append (*types, type);
-
-       if (!type->subtypes)
-               return;
-
-       for (i = 0; i < mono_array_length (type->subtypes); ++i) {
-               MonoReflectionTypeBuilder *subtype = mono_array_get (type->subtypes, MonoReflectionTypeBuilder*, i);
-               collect_types (types, subtype);
-       }
-}
-
-static gint
-compare_types_by_table_idx (MonoReflectionTypeBuilder **type1, MonoReflectionTypeBuilder **type2)
-{
-       if ((*type1)->table_idx < (*type2)->table_idx)
-               return -1;
-       else
-               if ((*type1)->table_idx > (*type2)->table_idx)
-                       return 1;
-       else
-               return 0;
-}
-
-static gboolean
-params_add_cattrs (MonoDynamicImage *assembly, MonoArray *pinfo, MonoError *error) {
-       int i;
-
-       mono_error_init (error);
-       if (!pinfo)
-               return TRUE;
-       for (i = 0; i < mono_array_length (pinfo); ++i) {
-               MonoReflectionParamBuilder *pb;
-               pb = mono_array_get (pinfo, MonoReflectionParamBuilder *, i);
-               if (!pb)
-                       continue;
-               if (!mono_image_add_cattrs (assembly, pb->table_idx, MONO_CUSTOM_ATTR_PARAMDEF, pb->cattrs, error))
-                       return FALSE;
-       }
-
-       return TRUE;
-}
-
-static gboolean
-type_add_cattrs (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *tb, MonoError *error) {
-       int i;
-
-       mono_error_init (error);
-       
-       if (!mono_image_add_cattrs (assembly, tb->table_idx, MONO_CUSTOM_ATTR_TYPEDEF, tb->cattrs, error))
-               return FALSE;
-       if (tb->fields) {
-               for (i = 0; i < tb->num_fields; ++i) {
-                       MonoReflectionFieldBuilder* fb;
-                       fb = mono_array_get (tb->fields, MonoReflectionFieldBuilder*, i);
-                       if (!mono_image_add_cattrs (assembly, fb->table_idx, MONO_CUSTOM_ATTR_FIELDDEF, fb->cattrs, error))
-                               return FALSE;
-               }
-       }
-       if (tb->events) {
-               for (i = 0; i < mono_array_length (tb->events); ++i) {
-                       MonoReflectionEventBuilder* eb;
-                       eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
-                       if (!mono_image_add_cattrs (assembly, eb->table_idx, MONO_CUSTOM_ATTR_EVENT, eb->cattrs, error))
-                               return FALSE;
-               }
-       }
-       if (tb->properties) {
-               for (i = 0; i < mono_array_length (tb->properties); ++i) {
-                       MonoReflectionPropertyBuilder* pb;
-                       pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
-                       if (!mono_image_add_cattrs (assembly, pb->table_idx, MONO_CUSTOM_ATTR_PROPERTY, pb->cattrs, error))
-                               return FALSE;
-               }
-       }
-       if (tb->ctors) {
-               for (i = 0; i < mono_array_length (tb->ctors); ++i) {
-                       MonoReflectionCtorBuilder* cb;
-                       cb = mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i);
-                       if (!mono_image_add_cattrs (assembly, cb->table_idx, MONO_CUSTOM_ATTR_METHODDEF, cb->cattrs, error) ||
-                           !params_add_cattrs (assembly, cb->pinfo, error))
-                               return FALSE;
-               }
-       }
-
-       if (tb->methods) {
-               for (i = 0; i < tb->num_methods; ++i) {
-                       MonoReflectionMethodBuilder* mb;
-                       mb = mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
-                       if (!mono_image_add_cattrs (assembly, mb->table_idx, MONO_CUSTOM_ATTR_METHODDEF, mb->cattrs, error) ||
-                           !params_add_cattrs (assembly, mb->pinfo, error))
-                               return FALSE;
-               }
-       }
-
-       if (tb->subtypes) {
-               for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
-                       if (!type_add_cattrs (assembly, mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i), error))
-                               return FALSE;
-               }
-       }
-
-       return TRUE;
-}
-
-static gboolean
-module_add_cattrs (MonoDynamicImage *assembly, MonoReflectionModuleBuilder *moduleb, MonoError *error)
-{
-       int i;
-       
-       mono_error_init (error);
-
-       if (!mono_image_add_cattrs (assembly, moduleb->table_idx, MONO_CUSTOM_ATTR_MODULE, moduleb->cattrs, error))
-               return FALSE;
-
-       if (moduleb->global_methods) {
-               for (i = 0; i < mono_array_length (moduleb->global_methods); ++i) {
-                       MonoReflectionMethodBuilder* mb = mono_array_get (moduleb->global_methods, MonoReflectionMethodBuilder*, i);
-                       if (!mono_image_add_cattrs (assembly, mb->table_idx, MONO_CUSTOM_ATTR_METHODDEF, mb->cattrs, error) ||
-                           !params_add_cattrs (assembly, mb->pinfo, error))
-                               return FALSE;
-               }
-       }
-
-       if (moduleb->global_fields) {
-               for (i = 0; i < mono_array_length (moduleb->global_fields); ++i) {
-                       MonoReflectionFieldBuilder *fb = mono_array_get (moduleb->global_fields, MonoReflectionFieldBuilder*, i);
-                       if (!mono_image_add_cattrs (assembly, fb->table_idx, MONO_CUSTOM_ATTR_FIELDDEF, fb->cattrs, error))
-                               return FALSE;
-               }
-       }
-       
-       if (moduleb->types) {
-               for (i = 0; i < moduleb->num_types; ++i) {
-                       if (!type_add_cattrs (assembly, mono_array_get (moduleb->types, MonoReflectionTypeBuilder*, i), error))
-                               return FALSE;
-               }
-       }
-
-       return TRUE;
-}
-
-static gboolean
-mono_image_fill_file_table (MonoDomain *domain, MonoReflectionModule *module, MonoDynamicImage *assembly, MonoError *error)
-{
-       MonoDynamicTable *table;
-       guint32 *values;
-       char blob_size [6];
-       guchar hash [20];
-       char *b = blob_size;
-       char *dir, *path;
-
-       mono_error_init (error);
-
-       table = &assembly->tables [MONO_TABLE_FILE];
-       table->rows++;
-       alloc_table (table, table->rows);
-       values = table->values + table->next_idx * MONO_FILE_SIZE;
-       values [MONO_FILE_FLAGS] = FILE_CONTAINS_METADATA;
-       values [MONO_FILE_NAME] = string_heap_insert (&assembly->sheap, module->image->module_name);
-       if (image_is_dynamic (module->image)) {
-               /* This depends on the fact that the main module is emitted last */
-               dir = mono_string_to_utf8_checked (((MonoReflectionModuleBuilder*)module)->assemblyb->dir, error);
-               return_val_if_nok (error, FALSE);
-               path = g_strdup_printf ("%s%c%s", dir, G_DIR_SEPARATOR, module->image->module_name);
-       } else {
-               dir = NULL;
-               path = g_strdup (module->image->name);
-       }
-       mono_sha1_get_digest_from_file (path, hash);
-       g_free (dir);
-       g_free (path);
-       mono_metadata_encode_value (20, b, &b);
-       values [MONO_FILE_HASH_VALUE] = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
-       mono_image_add_stream_data (&assembly->blob, (char*)hash, 20);
-       table->next_idx ++;
-       return TRUE;
-}
-
-static void
-mono_image_fill_module_table (MonoDomain *domain, MonoReflectionModuleBuilder *mb, MonoDynamicImage *assembly, MonoError *error)
-{
-       MonoDynamicTable *table;
-       int i;
-
-       mono_error_init (error);
-
-       table = &assembly->tables [MONO_TABLE_MODULE];
-       mb->table_idx = table->next_idx ++;
-       table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_NAME] = string_heap_insert_mstring (&assembly->sheap, mb->module.name, error);
-       return_if_nok (error);
-       i = mono_image_add_stream_data (&assembly->guid, mono_array_addr (mb->guid, char, 0), 16);
-       i /= 16;
-       ++i;
-       table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_GENERATION] = 0;
-       table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_MVID] = i;
-       table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_ENC] = 0;
-       table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_ENCBASE] = 0;
-}
-
-static guint32
-mono_image_fill_export_table_from_class (MonoDomain *domain, MonoClass *klass,
-       guint32 module_index, guint32 parent_index, MonoDynamicImage *assembly)
-{
-       MonoDynamicTable *table;
-       guint32 *values;
-       guint32 visib, res;
-
-       visib = klass->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK;
-       if (! ((visib & TYPE_ATTRIBUTE_PUBLIC) || (visib & TYPE_ATTRIBUTE_NESTED_PUBLIC)))
-               return 0;
-
-       table = &assembly->tables [MONO_TABLE_EXPORTEDTYPE];
-       table->rows++;
-       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_TYPEDEF] = klass->type_token;
-       if (klass->nested_in)
-               values [MONO_EXP_TYPE_IMPLEMENTATION] = (parent_index << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_EXP_TYPE;
-       else
-               values [MONO_EXP_TYPE_IMPLEMENTATION] = (module_index << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_FILE;
-       values [MONO_EXP_TYPE_NAME] = string_heap_insert (&assembly->sheap, klass->name);
-       values [MONO_EXP_TYPE_NAMESPACE] = string_heap_insert (&assembly->sheap, klass->name_space);
-
-       res = table->next_idx;
-
-       table->next_idx ++;
-
-       /* Emit nested types */
-       if (klass->ext && klass->ext->nested_classes) {
-               GList *tmp;
-
-               for (tmp = klass->ext->nested_classes; tmp; tmp = tmp->next)
-                       mono_image_fill_export_table_from_class (domain, (MonoClass *)tmp->data, module_index, table->next_idx - 1, assembly);
-       }
-
-       return res;
-}
-
-static void
-mono_image_fill_export_table (MonoDomain *domain, MonoReflectionTypeBuilder *tb,
-                             guint32 module_index, guint32 parent_index, MonoDynamicImage *assembly,
-                             MonoError *error)
-{
-       MonoClass *klass;
-       guint32 idx, i;
-
-       mono_error_init (error);
-
-       MonoType *t = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
-       return_if_nok (error);
-
-       klass = mono_class_from_mono_type (t);
-
-       klass->type_token = mono_metadata_make_token (MONO_TABLE_TYPEDEF, tb->table_idx);
-
-       idx = mono_image_fill_export_table_from_class (domain, klass, module_index, 
-                                                                                                  parent_index, assembly);
-
-       /* 
-        * Emit nested types
-        * We need to do this ourselves since klass->nested_classes is not set up.
-        */
-       if (tb->subtypes) {
-               for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
-                       mono_image_fill_export_table (domain, mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i), module_index, idx, assembly, error);
-                       return_if_nok (error);
-               }
-       }
-}
-
-static void
-mono_image_fill_export_table_from_module (MonoDomain *domain, MonoReflectionModule *module,
-       guint32 module_index, MonoDynamicImage *assembly)
-{
-       MonoImage *image = module->image;
-       MonoTableInfo  *t;
-       guint32 i;
-
-       t = &image->tables [MONO_TABLE_TYPEDEF];
-
-       for (i = 0; i < t->rows; ++i) {
-               MonoError error;
-               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)
-                       mono_image_fill_export_table_from_class (domain, klass, module_index, 0, assembly);
-       }
-}
-
-static void
-add_exported_type (MonoReflectionAssemblyBuilder *assemblyb, MonoDynamicImage *assembly, MonoClass *klass, guint32 parent_index)
-{
-       MonoDynamicTable *table;
-       guint32 *values;
-       guint32 scope, scope_idx, impl, current_idx;
-       gboolean forwarder = TRUE;
-       gpointer iter = NULL;
-       MonoClass *nested;
-
-       if (klass->nested_in) {
-               impl = (parent_index << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_EXP_TYPE;
-               forwarder = FALSE;
-       } else {
-               scope = resolution_scope_from_image (assembly, klass->image);
-               g_assert ((scope & MONO_RESOLUTION_SCOPE_MASK) == MONO_RESOLUTION_SCOPE_ASSEMBLYREF);
-               scope_idx = scope >> MONO_RESOLUTION_SCOPE_BITS;
-               impl = (scope_idx << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_ASSEMBLYREF;
-       }
-
-       table = &assembly->tables [MONO_TABLE_EXPORTEDTYPE];
-
-       table->rows++;
-       alloc_table (table, table->rows);
-       current_idx = table->next_idx;
-       values = table->values + current_idx * MONO_EXP_TYPE_SIZE;
-
-       values [MONO_EXP_TYPE_FLAGS] = forwarder ? TYPE_ATTRIBUTE_FORWARDER : 0;
-       values [MONO_EXP_TYPE_TYPEDEF] = 0;
-       values [MONO_EXP_TYPE_IMPLEMENTATION] = impl;
-       values [MONO_EXP_TYPE_NAME] = string_heap_insert (&assembly->sheap, klass->name);
-       values [MONO_EXP_TYPE_NAMESPACE] = string_heap_insert (&assembly->sheap, klass->name_space);
-
-       table->next_idx++;
-
-       while ((nested = mono_class_get_nested_types (klass, &iter)))
-               add_exported_type (assemblyb, assembly, nested, current_idx);
-}
-
-static void
-mono_image_fill_export_table_from_type_forwarders (MonoReflectionAssemblyBuilder *assemblyb, MonoDynamicImage *assembly)
-{
-       MonoError error;
-       MonoClass *klass;
-       int i;
-
-       if (!assemblyb->type_forwarders)
-               return;
-
-       for (i = 0; i < mono_array_length (assemblyb->type_forwarders); ++i) {
-               MonoReflectionType *t = mono_array_get (assemblyb->type_forwarders, MonoReflectionType *, i);
-               MonoType *type;
-               if (!t)
-                       continue;
-
-               type = mono_reflection_type_get_handle (t, &error);
-               mono_error_assert_ok (&error);
-               g_assert (type);
-
-               klass = mono_class_from_mono_type (type);
-
-               add_exported_type (assemblyb, assembly, klass, 0);
-       }
-}
-
-#define align_pointer(base,p)\
-       do {\
-               guint32 __diff = (unsigned char*)(p)-(unsigned char*)(base);\
-               if (__diff & 3)\
-                       (p) += 4 - (__diff & 3);\
-       } while (0)
-
-static int
-compare_constants (const void *a, const void *b)
-{
-       const guint32 *a_values = (const guint32 *)a;
-       const guint32 *b_values = (const guint32 *)b;
-       return a_values [MONO_CONSTANT_PARENT] - b_values [MONO_CONSTANT_PARENT];
-}
-
-static int
-compare_semantics (const void *a, const void *b)
-{
-       const guint32 *a_values = (const guint32 *)a;
-       const guint32 *b_values = (const guint32 *)b;
-       int assoc = a_values [MONO_METHOD_SEMA_ASSOCIATION] - b_values [MONO_METHOD_SEMA_ASSOCIATION];
-       if (assoc)
-               return assoc;
-       return a_values [MONO_METHOD_SEMA_SEMANTICS] - b_values [MONO_METHOD_SEMA_SEMANTICS];
-}
-
-static int
-compare_custom_attrs (const void *a, const void *b)
-{
-       const guint32 *a_values = (const guint32 *)a;
-       const guint32 *b_values = (const guint32 *)b;
-
-       return a_values [MONO_CUSTOM_ATTR_PARENT] - b_values [MONO_CUSTOM_ATTR_PARENT];
-}
-
-static int
-compare_field_marshal (const void *a, const void *b)
-{
-       const guint32 *a_values = (const guint32 *)a;
-       const guint32 *b_values = (const guint32 *)b;
-
-       return a_values [MONO_FIELD_MARSHAL_PARENT] - b_values [MONO_FIELD_MARSHAL_PARENT];
-}
-
-static int
-compare_nested (const void *a, const void *b)
-{
-       const guint32 *a_values = (const guint32 *)a;
-       const guint32 *b_values = (const guint32 *)b;
-
-       return a_values [MONO_NESTED_CLASS_NESTED] - b_values [MONO_NESTED_CLASS_NESTED];
-}
-
-static int
-compare_genericparam (const void *a, const void *b)
-{
-       MonoError error;
-       const GenericParamTableEntry **a_entry = (const GenericParamTableEntry **) a;
-       const GenericParamTableEntry **b_entry = (const GenericParamTableEntry **) b;
-
-       if ((*b_entry)->owner == (*a_entry)->owner) {
-               MonoType *a_type = mono_reflection_type_get_handle ((MonoReflectionType*)(*a_entry)->gparam, &error);
-               mono_error_assert_ok (&error);
-               MonoType *b_type = mono_reflection_type_get_handle ((MonoReflectionType*)(*b_entry)->gparam, &error);
-               mono_error_assert_ok (&error);
-               return 
-                       mono_type_get_generic_param_num (a_type) -
-                       mono_type_get_generic_param_num (b_type);
-       } else
-               return (*a_entry)->owner - (*b_entry)->owner;
-}
-
-static int
-compare_declsecurity_attrs (const void *a, const void *b)
-{
-       const guint32 *a_values = (const guint32 *)a;
-       const guint32 *b_values = (const guint32 *)b;
-
-       return a_values [MONO_DECL_SECURITY_PARENT] - b_values [MONO_DECL_SECURITY_PARENT];
-}
-
-static int
-compare_interface_impl (const void *a, const void *b)
-{
-       const guint32 *a_values = (const guint32 *)a;
-       const guint32 *b_values = (const guint32 *)b;
-
-       int klass = a_values [MONO_INTERFACEIMPL_CLASS] - b_values [MONO_INTERFACEIMPL_CLASS];
-       if (klass)
-               return klass;
-
-       return a_values [MONO_INTERFACEIMPL_INTERFACE] - b_values [MONO_INTERFACEIMPL_INTERFACE];
-}
-
-static void
-pad_heap (MonoDynamicStream *sh)
-{
-       if (sh->index & 3) {
-               int sz = 4 - (sh->index & 3);
-               memset (sh->data + sh->index, 0, sz);
-               sh->index += sz;
-       }
-}
-
-struct StreamDesc {
-       const char *name;
-       MonoDynamicStream *stream;
-};
-
-/*
- * build_compressed_metadata() fills in the blob of data that represents the 
- * raw metadata as it will be saved in the PE file. The five streams are output 
- * and the metadata tables are comnpressed from the guint32 array representation, 
- * to the compressed on-disk format.
- */
-static gboolean
-build_compressed_metadata (MonoDynamicImage *assembly, MonoError *error)
-{
-       MonoDynamicTable *table;
-       int i;
-       guint64 valid_mask = 0;
-       guint64 sorted_mask;
-       guint32 heapt_size = 0;
-       guint32 meta_size = 256; /* allow for header and other stuff */
-       guint32 table_offset;
-       guint32 ntables = 0;
-       guint64 *int64val;
-       guint32 *int32val;
-       guint16 *int16val;
-       MonoImage *meta;
-       unsigned char *p;
-       struct StreamDesc stream_desc [5];
-
-       mono_error_init (error);
-
-       qsort (assembly->gen_params->pdata, assembly->gen_params->len, sizeof (gpointer), compare_genericparam);
-       for (i = 0; i < assembly->gen_params->len; i++) {
-               GenericParamTableEntry *entry = (GenericParamTableEntry *)g_ptr_array_index (assembly->gen_params, i);
-               if (!write_generic_param_entry (assembly, entry, error))
-                       return FALSE;
-       }
-
-       stream_desc [0].name  = "#~";
-       stream_desc [0].stream = &assembly->tstream;
-       stream_desc [1].name  = "#Strings";
-       stream_desc [1].stream = &assembly->sheap;
-       stream_desc [2].name  = "#US";
-       stream_desc [2].stream = &assembly->us;
-       stream_desc [3].name  = "#Blob";
-       stream_desc [3].stream = &assembly->blob;
-       stream_desc [4].name  = "#GUID";
-       stream_desc [4].stream = &assembly->guid;
-       
-       /* tables that are sorted */
-       sorted_mask = ((guint64)1 << MONO_TABLE_CONSTANT) | ((guint64)1 << MONO_TABLE_FIELDMARSHAL)
-               | ((guint64)1 << MONO_TABLE_METHODSEMANTICS) | ((guint64)1 << MONO_TABLE_CLASSLAYOUT)
-               | ((guint64)1 << MONO_TABLE_FIELDLAYOUT) | ((guint64)1 << MONO_TABLE_FIELDRVA)
-               | ((guint64)1 << MONO_TABLE_IMPLMAP) | ((guint64)1 << MONO_TABLE_NESTEDCLASS)
-               | ((guint64)1 << MONO_TABLE_METHODIMPL) | ((guint64)1 << MONO_TABLE_CUSTOMATTRIBUTE)
-               | ((guint64)1 << MONO_TABLE_DECLSECURITY) | ((guint64)1 << MONO_TABLE_GENERICPARAM)
-               | ((guint64)1 << MONO_TABLE_INTERFACEIMPL);
-       
-       /* Compute table sizes */
-       /* the MonoImage has already been created in mono_image_basic_init() */
-       meta = &assembly->image;
-
-       /* sizes should be multiple of 4 */
-       pad_heap (&assembly->blob);
-       pad_heap (&assembly->guid);
-       pad_heap (&assembly->sheap);
-       pad_heap (&assembly->us);
-
-       /* Setup the info used by compute_sizes () */
-       meta->idx_blob_wide = assembly->blob.index >= 65536 ? 1 : 0;
-       meta->idx_guid_wide = assembly->guid.index >= 65536 ? 1 : 0;
-       meta->idx_string_wide = assembly->sheap.index >= 65536 ? 1 : 0;
-
-       meta_size += assembly->blob.index;
-       meta_size += assembly->guid.index;
-       meta_size += assembly->sheap.index;
-       meta_size += assembly->us.index;
-
-       for (i=0; i < MONO_TABLE_NUM; ++i)
-               meta->tables [i].rows = assembly->tables [i].rows;
-       
-       for (i = 0; i < MONO_TABLE_NUM; i++){
-               if (meta->tables [i].rows == 0)
-                       continue;
-               valid_mask |= (guint64)1 << i;
-               ntables ++;
-               meta->tables [i].row_size = mono_metadata_compute_size (
-                       meta, i, &meta->tables [i].size_bitfield);
-               heapt_size += meta->tables [i].row_size * meta->tables [i].rows;
-       }
-       heapt_size += 24; /* #~ header size */
-       heapt_size += ntables * 4;
-       /* make multiple of 4 */
-       heapt_size += 3;
-       heapt_size &= ~3;
-       meta_size += heapt_size;
-       meta->raw_metadata = (char *)g_malloc0 (meta_size);
-       p = (unsigned char*)meta->raw_metadata;
-       /* the metadata signature */
-       *p++ = 'B'; *p++ = 'S'; *p++ = 'J'; *p++ = 'B';
-       /* version numbers and 4 bytes reserved */
-       int16val = (guint16*)p;
-       *int16val++ = GUINT16_TO_LE (meta->md_version_major);
-       *int16val = GUINT16_TO_LE (meta->md_version_minor);
-       p += 8;
-       /* version string */
-       int32val = (guint32*)p;
-       *int32val = GUINT32_TO_LE ((strlen (meta->version) + 3) & (~3)); /* needs to be multiple of 4 */
-       p += 4;
-       memcpy (p, meta->version, strlen (meta->version));
-       p += GUINT32_FROM_LE (*int32val);
-       align_pointer (meta->raw_metadata, p);
-       int16val = (guint16*)p;
-       *int16val++ = GUINT16_TO_LE (0); /* flags must be 0 */
-       *int16val = GUINT16_TO_LE (5); /* number of streams */
-       p += 4;
-
-       /*
-        * write the stream info.
-        */
-       table_offset = (p - (unsigned char*)meta->raw_metadata) + 5 * 8 + 40; /* room needed for stream headers */
-       table_offset += 3; table_offset &= ~3;
-
-       assembly->tstream.index = heapt_size;
-       for (i = 0; i < 5; ++i) {
-               int32val = (guint32*)p;
-               stream_desc [i].stream->offset = table_offset;
-               *int32val++ = GUINT32_TO_LE (table_offset);
-               *int32val = GUINT32_TO_LE (stream_desc [i].stream->index);
-               table_offset += GUINT32_FROM_LE (*int32val);
-               table_offset += 3; table_offset &= ~3;
-               p += 8;
-               strcpy ((char*)p, stream_desc [i].name);
-               p += strlen (stream_desc [i].name) + 1;
-               align_pointer (meta->raw_metadata, p);
-       }
-       /* 
-        * now copy the data, the table stream header and contents goes first.
-        */
-       g_assert ((p - (unsigned char*)meta->raw_metadata) < assembly->tstream.offset);
-       p = (guchar*)meta->raw_metadata + assembly->tstream.offset;
-       int32val = (guint32*)p;
-       *int32val = GUINT32_TO_LE (0); /* reserved */
-       p += 4;
-
-       *p++ = 2; /* version */
-       *p++ = 0;
-
-       if (meta->idx_string_wide)
-               *p |= 0x01;
-       if (meta->idx_guid_wide)
-               *p |= 0x02;
-       if (meta->idx_blob_wide)
-               *p |= 0x04;
-       ++p;
-       *p++ = 1; /* reserved */
-       int64val = (guint64*)p;
-       *int64val++ = GUINT64_TO_LE (valid_mask);
-       *int64val++ = GUINT64_TO_LE (valid_mask & sorted_mask); /* bitvector of sorted tables  */
-       p += 16;
-       int32val = (guint32*)p;
-       for (i = 0; i < MONO_TABLE_NUM; i++){
-               if (meta->tables [i].rows == 0)
-                       continue;
-               *int32val++ = GUINT32_TO_LE (meta->tables [i].rows);
-       }
-       p = (unsigned char*)int32val;
-
-       /* sort the tables that still need sorting */
-       table = &assembly->tables [MONO_TABLE_CONSTANT];
-       if (table->rows)
-               qsort (table->values + MONO_CONSTANT_SIZE, table->rows, sizeof (guint32) * MONO_CONSTANT_SIZE, compare_constants);
-       table = &assembly->tables [MONO_TABLE_METHODSEMANTICS];
-       if (table->rows)
-               qsort (table->values + MONO_METHOD_SEMA_SIZE, table->rows, sizeof (guint32) * MONO_METHOD_SEMA_SIZE, compare_semantics);
-       table = &assembly->tables [MONO_TABLE_CUSTOMATTRIBUTE];
-       if (table->rows)
-               qsort (table->values + MONO_CUSTOM_ATTR_SIZE, table->rows, sizeof (guint32) * MONO_CUSTOM_ATTR_SIZE, compare_custom_attrs);
-       table = &assembly->tables [MONO_TABLE_FIELDMARSHAL];
-       if (table->rows)
-               qsort (table->values + MONO_FIELD_MARSHAL_SIZE, table->rows, sizeof (guint32) * MONO_FIELD_MARSHAL_SIZE, compare_field_marshal);
-       table = &assembly->tables [MONO_TABLE_NESTEDCLASS];
-       if (table->rows)
-               qsort (table->values + MONO_NESTED_CLASS_SIZE, table->rows, sizeof (guint32) * MONO_NESTED_CLASS_SIZE, compare_nested);
-       /* Section 21.11 DeclSecurity in Partition II doesn't specify this to be sorted by MS implementation requires it */
-       table = &assembly->tables [MONO_TABLE_DECLSECURITY];
-       if (table->rows)
-               qsort (table->values + MONO_DECL_SECURITY_SIZE, table->rows, sizeof (guint32) * MONO_DECL_SECURITY_SIZE, compare_declsecurity_attrs);
-       table = &assembly->tables [MONO_TABLE_INTERFACEIMPL];
-       if (table->rows)
-               qsort (table->values + MONO_INTERFACEIMPL_SIZE, table->rows, sizeof (guint32) * MONO_INTERFACEIMPL_SIZE, compare_interface_impl);
-
-       /* compress the tables */
-       for (i = 0; i < MONO_TABLE_NUM; i++){
-               int row, col;
-               guint32 *values;
-               guint32 bitfield = meta->tables [i].size_bitfield;
-               if (!meta->tables [i].rows)
-                       continue;
-               if (assembly->tables [i].columns != mono_metadata_table_count (bitfield))
-                       g_error ("col count mismatch in %d: %d %d", i, assembly->tables [i].columns, mono_metadata_table_count (bitfield));
-               meta->tables [i].base = (char*)p;
-               for (row = 1; row <= meta->tables [i].rows; ++row) {
-                       values = assembly->tables [i].values + row * assembly->tables [i].columns;
-                       for (col = 0; col < assembly->tables [i].columns; ++col) {
-                               switch (mono_metadata_table_size (bitfield, col)) {
-                               case 1:
-                                       *p++ = values [col];
-                                       break;
-                               case 2:
-                                       *p++ = values [col] & 0xff;
-                                       *p++ = (values [col] >> 8) & 0xff;
-                                       break;
-                               case 4:
-                                       *p++ = values [col] & 0xff;
-                                       *p++ = (values [col] >> 8) & 0xff;
-                                       *p++ = (values [col] >> 16) & 0xff;
-                                       *p++ = (values [col] >> 24) & 0xff;
-                                       break;
-                               default:
-                                       g_assert_not_reached ();
-                               }
-                       }
-               }
-               g_assert ((p - (const unsigned char*)meta->tables [i].base) == (meta->tables [i].rows * meta->tables [i].row_size));
-       }
-       
-       g_assert (assembly->guid.offset + assembly->guid.index < meta_size);
-       memcpy (meta->raw_metadata + assembly->sheap.offset, assembly->sheap.data, assembly->sheap.index);
-       memcpy (meta->raw_metadata + assembly->us.offset, assembly->us.data, assembly->us.index);
-       memcpy (meta->raw_metadata + assembly->blob.offset, assembly->blob.data, assembly->blob.index);
-       memcpy (meta->raw_metadata + assembly->guid.offset, assembly->guid.data, assembly->guid.index);
-
-       assembly->meta_size = assembly->guid.offset + assembly->guid.index;
-
-       return TRUE;
-}
-
-/*
- * Some tables in metadata need to be sorted according to some criteria, but
- * when methods and fields are first created with reflection, they may be assigned a token
- * that doesn't correspond to the final token they will get assigned after the sorting.
- * ILGenerator.cs keeps a fixup table that maps the position of tokens in the IL code stream
- * with the reflection objects that represent them. Once all the tables are set up, the 
- * reflection objects will contains the correct table index. fixup_method() will fixup the
- * tokens for the method with ILGenerator @ilgen.
- */
-static void
-fixup_method (MonoReflectionILGen *ilgen, gpointer value, MonoDynamicImage *assembly)
-{
-       guint32 code_idx = GPOINTER_TO_UINT (value);
-       MonoReflectionILTokenInfo *iltoken;
-       MonoReflectionFieldBuilder *field;
-       MonoReflectionCtorBuilder *ctor;
-       MonoReflectionMethodBuilder *method;
-       MonoReflectionTypeBuilder *tb;
-       MonoReflectionArrayMethod *am;
-       guint32 i, idx = 0;
-       unsigned char *target;
-
-       for (i = 0; i < ilgen->num_token_fixups; ++i) {
-               iltoken = (MonoReflectionILTokenInfo *)mono_array_addr_with_size (ilgen->token_fixups, sizeof (MonoReflectionILTokenInfo), i);
-               target = (guchar*)assembly->code.data + code_idx + iltoken->code_pos;
-               switch (target [3]) {
-               case MONO_TABLE_FIELD:
-                       if (!strcmp (iltoken->member->vtable->klass->name, "FieldBuilder")) {
-                               field = (MonoReflectionFieldBuilder *)iltoken->member;
-                               idx = field->table_idx;
-                       } else if (!strcmp (iltoken->member->vtable->klass->name, "MonoField")) {
-                               MonoClassField *f = ((MonoReflectionField*)iltoken->member)->field;
-                               idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->field_to_table_idx, f));
-                       } else {
-                               g_assert_not_reached ();
-                       }
-                       break;
-               case MONO_TABLE_METHOD:
-                       if (!strcmp (iltoken->member->vtable->klass->name, "MethodBuilder")) {
-                               method = (MonoReflectionMethodBuilder *)iltoken->member;
-                               idx = method->table_idx;
-                       } else if (!strcmp (iltoken->member->vtable->klass->name, "ConstructorBuilder")) {
-                               ctor = (MonoReflectionCtorBuilder *)iltoken->member;
-                               idx = ctor->table_idx;
-                       } else if (!strcmp (iltoken->member->vtable->klass->name, "MonoMethod") || 
-                                          !strcmp (iltoken->member->vtable->klass->name, "MonoCMethod")) {
-                               MonoMethod *m = ((MonoReflectionMethod*)iltoken->member)->method;
-                               idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->method_to_table_idx, m));
-                       } else {
-                               g_assert_not_reached ();
-                       }
-                       break;
-               case MONO_TABLE_TYPEDEF:
-                       if (strcmp (iltoken->member->vtable->klass->name, "TypeBuilder"))
-                               g_assert_not_reached ();
-                       tb = (MonoReflectionTypeBuilder *)iltoken->member;
-                       idx = tb->table_idx;
-                       break;
-               case MONO_TABLE_MEMBERREF:
-                       if (!strcmp (iltoken->member->vtable->klass->name, "MonoArrayMethod")) {
-                               am = (MonoReflectionArrayMethod*)iltoken->member;
-                               idx = am->table_idx;
-                       } else if (!strcmp (iltoken->member->vtable->klass->name, "MonoMethod") ||
-                                  !strcmp (iltoken->member->vtable->klass->name, "MonoCMethod") ||
-                                  !strcmp (iltoken->member->vtable->klass->name, "MonoGenericMethod") ||
-                                  !strcmp (iltoken->member->vtable->klass->name, "MonoGenericCMethod")) {
-                               MonoMethod *m = ((MonoReflectionMethod*)iltoken->member)->method;
-                               g_assert (m->klass->generic_class || m->klass->generic_container);
-                               continue;
-                       } else if (!strcmp (iltoken->member->vtable->klass->name, "FieldBuilder")) {
-                               continue;
-                       } else if (!strcmp (iltoken->member->vtable->klass->name, "MonoField")) {
-                               MonoClassField *f = ((MonoReflectionField*)iltoken->member)->field;
-                               g_assert (is_field_on_inst (f));
-                               continue;
-                       } else if (!strcmp (iltoken->member->vtable->klass->name, "MethodBuilder") ||
-                                       !strcmp (iltoken->member->vtable->klass->name, "ConstructorBuilder")) {
-                               continue;
-                       } else if (!strcmp (iltoken->member->vtable->klass->name, "FieldOnTypeBuilderInst")) {
-                               continue;
-                       } else if (!strcmp (iltoken->member->vtable->klass->name, "MethodOnTypeBuilderInst")) {
-                               continue;
-                       } else if (!strcmp (iltoken->member->vtable->klass->name, "ConstructorOnTypeBuilderInst")) {
-                               continue;
-                       } else {
-                               g_assert_not_reached ();
-                       }
-                       break;
-               case MONO_TABLE_METHODSPEC:
-                       if (!strcmp (iltoken->member->vtable->klass->name, "MonoGenericMethod")) {
-                               MonoMethod *m = ((MonoReflectionMethod*)iltoken->member)->method;
-                               g_assert (mono_method_signature (m)->generic_param_count);
-                               continue;
-                       } else if (!strcmp (iltoken->member->vtable->klass->name, "MethodBuilder")) {
-                               continue;
-                       } else if (!strcmp (iltoken->member->vtable->klass->name, "MethodOnTypeBuilderInst")) {
-                               continue;
-                       } else {
-                               g_assert_not_reached ();
-                       }
-                       break;
-               default:
-                       g_error ("got unexpected table 0x%02x in fixup", target [3]);
-               }
-               target [0] = idx & 0xff;
-               target [1] = (idx >> 8) & 0xff;
-               target [2] = (idx >> 16) & 0xff;
-       }
-}
-
-/*
- * fixup_cattrs:
- *
- *   The CUSTOM_ATTRIBUTE table might contain METHODDEF tokens whose final
- * value is not known when the table is emitted.
- */
-static void
-fixup_cattrs (MonoDynamicImage *assembly)
-{
-       MonoDynamicTable *table;
-       guint32 *values;
-       guint32 type, i, idx, token;
-       MonoObject *ctor;
-
-       table = &assembly->tables [MONO_TABLE_CUSTOMATTRIBUTE];
-
-       for (i = 0; i < table->rows; ++i) {
-               values = table->values + ((i + 1) * MONO_CUSTOM_ATTR_SIZE);
-
-               type = values [MONO_CUSTOM_ATTR_TYPE];
-               if ((type & MONO_CUSTOM_ATTR_TYPE_MASK) == MONO_CUSTOM_ATTR_TYPE_METHODDEF) {
-                       idx = type >> MONO_CUSTOM_ATTR_TYPE_BITS;
-                       token = mono_metadata_make_token (MONO_TABLE_METHOD, idx);
-                       ctor = (MonoObject *)mono_g_hash_table_lookup (assembly->remapped_tokens, GUINT_TO_POINTER (token));
-                       g_assert (ctor);
-
-                       if (!strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
-                               MonoMethod *m = ((MonoReflectionMethod*)ctor)->method;
-                               idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->method_to_table_idx, m));
-                               values [MONO_CUSTOM_ATTR_TYPE] = (idx << MONO_CUSTOM_ATTR_TYPE_BITS) | MONO_CUSTOM_ATTR_TYPE_METHODDEF;
-                       } else if (!strcmp (ctor->vtable->klass->name, "ConstructorBuilder")) {
-                               MonoMethod *m = ((MonoReflectionCtorBuilder*)ctor)->mhandle;
-                               idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->method_to_table_idx, m));
-                               values [MONO_CUSTOM_ATTR_TYPE] = (idx << MONO_CUSTOM_ATTR_TYPE_BITS) | MONO_CUSTOM_ATTR_TYPE_METHODDEF;
-                       }
-               }
-       }
-}
-
-static gboolean
-assembly_add_resource_manifest (MonoReflectionModuleBuilder *mb, MonoDynamicImage *assembly, MonoReflectionResource *rsrc, guint32 implementation, MonoError *error)
-{
-       MonoDynamicTable *table;
-       guint32 *values;
-
-       mono_error_init (error);
-
-       table = &assembly->tables [MONO_TABLE_MANIFESTRESOURCE];
-       table->rows++;
-       alloc_table (table, table->rows);
-       values = table->values + table->next_idx * MONO_MANIFEST_SIZE;
-       values [MONO_MANIFEST_OFFSET] = rsrc->offset;
-       values [MONO_MANIFEST_FLAGS] = rsrc->attrs;
-       values [MONO_MANIFEST_NAME] = string_heap_insert_mstring (&assembly->sheap, rsrc->name, error);
-       return_val_if_nok (error, FALSE);
-       values [MONO_MANIFEST_IMPLEMENTATION] = implementation;
-       table->next_idx++;
-       return TRUE;
-}
-
-static gboolean
-assembly_add_resource (MonoReflectionModuleBuilder *mb, MonoDynamicImage *assembly, MonoReflectionResource *rsrc, MonoError *error)
-{
-       MonoDynamicTable *table;
-       guint32 *values;
-       char blob_size [6];
-       guchar hash [20];
-       char *b = blob_size;
-       char *name, *sname;
-       guint32 idx, offset;
-
-       mono_error_init (error);
-
-       if (rsrc->filename) {
-               name = mono_string_to_utf8_checked (rsrc->filename, error);
-               return_val_if_nok (error, FALSE);
-               sname = g_path_get_basename (name);
-       
-               table = &assembly->tables [MONO_TABLE_FILE];
-               table->rows++;
-               alloc_table (table, table->rows);
-               values = table->values + table->next_idx * MONO_FILE_SIZE;
-               values [MONO_FILE_FLAGS] = FILE_CONTAINS_NO_METADATA;
-               values [MONO_FILE_NAME] = string_heap_insert (&assembly->sheap, sname);
-               g_free (sname);
-
-               mono_sha1_get_digest_from_file (name, hash);
-               mono_metadata_encode_value (20, b, &b);
-               values [MONO_FILE_HASH_VALUE] = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
-               mono_image_add_stream_data (&assembly->blob, (char*)hash, 20);
-               g_free (name);
-               idx = table->next_idx++;
-               rsrc->offset = 0;
-               idx = MONO_IMPLEMENTATION_FILE | (idx << MONO_IMPLEMENTATION_BITS);
-       } else {
-               char sizebuf [4];
-               char *data;
-               guint len;
-               if (rsrc->data) {
-                       data = mono_array_addr (rsrc->data, char, 0);
-                       len = mono_array_length (rsrc->data);
-               } else {
-                       data = NULL;
-                       len = 0;
-               }
-               offset = len;
-               sizebuf [0] = offset; sizebuf [1] = offset >> 8;
-               sizebuf [2] = offset >> 16; sizebuf [3] = offset >> 24;
-               rsrc->offset = mono_image_add_stream_data (&assembly->resources, sizebuf, 4);
-               mono_image_add_stream_data (&assembly->resources, data, len);
-
-               if (!mb->is_main)
-                       /* 
-                        * The entry should be emitted into the MANIFESTRESOURCE table of 
-                        * the main module, but that needs to reference the FILE table
-                        * which isn't emitted yet.
-                        */
-                       return TRUE;
-               else
-                       idx = 0;
-       }
-
-       return assembly_add_resource_manifest (mb, assembly, rsrc, idx, error);
-}
-
-static gboolean
-set_version_from_string (MonoString *version, guint32 *values, MonoError *error)
-{
-       gchar *ver, *p, *str;
-       guint32 i;
-       
-       mono_error_init (error);
-
-       values [MONO_ASSEMBLY_MAJOR_VERSION] = 0;
-       values [MONO_ASSEMBLY_MINOR_VERSION] = 0;
-       values [MONO_ASSEMBLY_REV_NUMBER] = 0;
-       values [MONO_ASSEMBLY_BUILD_NUMBER] = 0;
-       if (!version)
-               return TRUE;
-       ver = str = mono_string_to_utf8_checked (version, error);
-       return_val_if_nok (error, FALSE);
-       for (i = 0; i < 4; ++i) {
-               values [MONO_ASSEMBLY_MAJOR_VERSION + i] = strtol (ver, &p, 10);
-               switch (*p) {
-               case '.':
-                       p++;
-                       break;
-               case '*':
-                       /* handle Revision and Build */
-                       p++;
-                       break;
-               }
-               ver = p;
-       }
-       g_free (str);
-       return TRUE;
-}
-
-static guint32
-load_public_key (MonoArray *pkey, MonoDynamicImage *assembly) {
-       gsize len;
-       guint32 token = 0;
-       char blob_size [6];
-       char *b = blob_size;
-
-       if (!pkey)
-               return token;
-
-       len = mono_array_length (pkey);
-       mono_metadata_encode_value (len, b, &b);
-       token = mono_image_add_stream_data (&assembly->blob, blob_size, b - blob_size);
-       mono_image_add_stream_data (&assembly->blob, mono_array_addr (pkey, char, 0), len);
-
-       assembly->public_key = (guint8 *)g_malloc (len);
-       memcpy (assembly->public_key, mono_array_addr (pkey, char, 0), len);
-       assembly->public_key_len = len;
-
-       /* Special case: check for ECMA key (16 bytes) */
-       if ((len == MONO_ECMA_KEY_LENGTH) && mono_is_ecma_key (mono_array_addr (pkey, char, 0), len)) {
-               /* In this case we must reserve 128 bytes (1024 bits) for the signature */
-               assembly->strong_name_size = MONO_DEFAULT_PUBLIC_KEY_LENGTH;
-       } else if (len >= MONO_PUBLIC_KEY_HEADER_LENGTH + MONO_MINIMUM_PUBLIC_KEY_LENGTH) {
-               /* minimum key size (in 2.0) is 384 bits */
-               assembly->strong_name_size = len - MONO_PUBLIC_KEY_HEADER_LENGTH;
-       } else {
-               /* FIXME - verifier */
-               g_warning ("Invalid public key length: %d bits (total: %d)", (int)MONO_PUBLIC_KEY_BIT_SIZE (len), (int)len);
-               assembly->strong_name_size = MONO_DEFAULT_PUBLIC_KEY_LENGTH; /* to be safe */
-       }
-       assembly->strong_name = (char *)g_malloc0 (assembly->strong_name_size);
-
-       return token;
-}
-
-static gboolean
-mono_image_emit_manifest (MonoReflectionModuleBuilder *moduleb, MonoError *error)
-{
-       MonoDynamicTable *table;
-       MonoDynamicImage *assembly;
-       MonoReflectionAssemblyBuilder *assemblyb;
-       MonoDomain *domain;
-       guint32 *values;
-       int i;
-       guint32 module_index;
-
-       mono_error_init (error);
-
-       assemblyb = moduleb->assemblyb;
-       assembly = moduleb->dynamic_image;
-       domain = mono_object_domain (assemblyb);
-
-       /* Emit ASSEMBLY table */
-       table = &assembly->tables [MONO_TABLE_ASSEMBLY];
-       alloc_table (table, 1);
-       values = table->values + MONO_ASSEMBLY_SIZE;
-       values [MONO_ASSEMBLY_HASH_ALG] = assemblyb->algid? assemblyb->algid: ASSEMBLY_HASH_SHA1;
-       values [MONO_ASSEMBLY_NAME] = string_heap_insert_mstring (&assembly->sheap, assemblyb->name, error);
-       return_val_if_nok (error, FALSE);
-       if (assemblyb->culture) {
-               values [MONO_ASSEMBLY_CULTURE] = string_heap_insert_mstring (&assembly->sheap, assemblyb->culture, error);
-               return_val_if_nok (error, FALSE);
-       } else {
-               values [MONO_ASSEMBLY_CULTURE] = string_heap_insert (&assembly->sheap, "");
-       }
-       values [MONO_ASSEMBLY_PUBLIC_KEY] = load_public_key (assemblyb->public_key, assembly);
-       values [MONO_ASSEMBLY_FLAGS] = assemblyb->flags;
-       if (!set_version_from_string (assemblyb->version, values, error))
-               return FALSE;
-
-       /* Emit FILE + EXPORTED_TYPE table */
-       module_index = 0;
-       for (i = 0; i < mono_array_length (assemblyb->modules); ++i) {
-               int j;
-               MonoReflectionModuleBuilder *file_module = 
-                       mono_array_get (assemblyb->modules, MonoReflectionModuleBuilder*, i);
-               if (file_module != moduleb) {
-                       if (!mono_image_fill_file_table (domain, (MonoReflectionModule*)file_module, assembly, error))
-                               return FALSE;
-                       module_index ++;
-                       if (file_module->types) {
-                               for (j = 0; j < file_module->num_types; ++j) {
-                                       MonoReflectionTypeBuilder *tb = mono_array_get (file_module->types, MonoReflectionTypeBuilder*, j);
-                                       mono_image_fill_export_table (domain, tb, module_index, 0, assembly, error);
-                                       return_val_if_nok (error, FALSE);
-                               }
-                       }
-               }
-       }
-       if (assemblyb->loaded_modules) {
-               for (i = 0; i < mono_array_length (assemblyb->loaded_modules); ++i) {
-                       MonoReflectionModule *file_module = 
-                               mono_array_get (assemblyb->loaded_modules, MonoReflectionModule*, i);
-                       if (!mono_image_fill_file_table (domain, file_module, assembly, error))
-                               return FALSE;
-                       module_index ++;
-                       mono_image_fill_export_table_from_module (domain, file_module, module_index, assembly);
-               }
-       }
-       if (assemblyb->type_forwarders)
-               mono_image_fill_export_table_from_type_forwarders (assemblyb, assembly);
-
-       /* Emit MANIFESTRESOURCE table */
-       module_index = 0;
-       for (i = 0; i < mono_array_length (assemblyb->modules); ++i) {
-               int j;
-               MonoReflectionModuleBuilder *file_module = 
-                       mono_array_get (assemblyb->modules, MonoReflectionModuleBuilder*, i);
-               /* The table for the main module is emitted later */
-               if (file_module != moduleb) {
-                       module_index ++;
-                       if (file_module->resources) {
-                               int len = mono_array_length (file_module->resources);
-                               for (j = 0; j < len; ++j) {
-                                       MonoReflectionResource* res = (MonoReflectionResource*)mono_array_addr (file_module->resources, MonoReflectionResource, j);
-                                       if (!assembly_add_resource_manifest (file_module, assembly, res, MONO_IMPLEMENTATION_FILE | (module_index << MONO_IMPLEMENTATION_BITS), error))
-                                               return FALSE;
-                               }
-                       }
-               }
-       }
-       return TRUE;
-}
-
-#ifndef DISABLE_REFLECTION_EMIT_SAVE
-
-/*
- * mono_image_build_metadata() will fill the info in all the needed metadata tables
- * for the modulebuilder @moduleb.
- * At the end of the process, method and field tokens are fixed up and the 
- * on-disk compressed metadata representation is created.
- * Return TRUE on success, or FALSE on failure and sets @error
- */
-gboolean
-mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb, MonoError *error)
-{
-       MonoDynamicTable *table;
-       MonoDynamicImage *assembly;
-       MonoReflectionAssemblyBuilder *assemblyb;
-       MonoDomain *domain;
-       MonoPtrArray types;
-       guint32 *values;
-       int i, j;
-
-       mono_error_init (error);
-
-       assemblyb = moduleb->assemblyb;
-       assembly = moduleb->dynamic_image;
-       domain = mono_object_domain (assemblyb);
-
-       if (assembly->text_rva)
-               return TRUE;
-
-       assembly->text_rva = START_TEXT_RVA;
-
-       if (moduleb->is_main) {
-               mono_image_emit_manifest (moduleb, error);
-               return_val_if_nok (error, FALSE);
-       }
-
-       table = &assembly->tables [MONO_TABLE_TYPEDEF];
-       table->rows = 1; /* .<Module> */
-       table->next_idx++;
-       alloc_table (table, table->rows);
-       /*
-        * Set the first entry.
-        */
-       values = table->values + table->columns;
-       values [MONO_TYPEDEF_FLAGS] = 0;
-       values [MONO_TYPEDEF_NAME] = string_heap_insert (&assembly->sheap, "<Module>") ;
-       values [MONO_TYPEDEF_NAMESPACE] = string_heap_insert (&assembly->sheap, "") ;
-       values [MONO_TYPEDEF_EXTENDS] = 0;
-       values [MONO_TYPEDEF_FIELD_LIST] = 1;
-       values [MONO_TYPEDEF_METHOD_LIST] = 1;
-
-       /* 
-        * handle global methods 
-        * FIXME: test what to do when global methods are defined in multiple modules.
-        */
-       if (moduleb->global_methods) {
-               table = &assembly->tables [MONO_TABLE_METHOD];
-               table->rows += mono_array_length (moduleb->global_methods);
-               alloc_table (table, table->rows);
-               for (i = 0; i < mono_array_length (moduleb->global_methods); ++i) {
-                       if (!mono_image_get_method_info (
-                                   mono_array_get (moduleb->global_methods, MonoReflectionMethodBuilder*, i), assembly, error))
-                               goto leave;
-               }
-       }
-       if (moduleb->global_fields) {
-               table = &assembly->tables [MONO_TABLE_FIELD];
-               table->rows += mono_array_length (moduleb->global_fields);
-               alloc_table (table, table->rows);
-               for (i = 0; i < mono_array_length (moduleb->global_fields); ++i) {
-                       mono_image_get_field_info (
-                               mono_array_get (moduleb->global_fields, MonoReflectionFieldBuilder*, i), assembly,
-                               error);
-                       if (!is_ok (error))
-                               goto leave;
-               }
-       }
-
-       table = &assembly->tables [MONO_TABLE_MODULE];
-       alloc_table (table, 1);
-       mono_image_fill_module_table (domain, moduleb, assembly, error);
-       if (!is_ok (error))
-               goto leave;
-
-       /* Collect all types into a list sorted by their table_idx */
-       mono_ptr_array_init (types, moduleb->num_types, MONO_ROOT_SOURCE_REFLECTION, "dynamic module types list");
-
-       if (moduleb->types)
-               for (i = 0; i < moduleb->num_types; ++i) {
-                       MonoReflectionTypeBuilder *type = mono_array_get (moduleb->types, MonoReflectionTypeBuilder*, i);
-                       collect_types (&types, type);
-               }
-
-       mono_ptr_array_sort (types, (int (*)(const void *, const void *))compare_types_by_table_idx);
-       table = &assembly->tables [MONO_TABLE_TYPEDEF];
-       table->rows += mono_ptr_array_size (types);
-       alloc_table (table, table->rows);
-
-       /*
-        * Emit type names + namespaces at one place inside the string heap,
-        * so load_class_names () needs to touch fewer pages.
-        */
-       for (i = 0; i < mono_ptr_array_size (types); ++i) {
-               MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_ptr_array_get (types, i);
-               string_heap_insert_mstring (&assembly->sheap, tb->nspace, error);
-               if (!is_ok (error))
-                       goto leave_types;
-       }
-       for (i = 0; i < mono_ptr_array_size (types); ++i) {
-               MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_ptr_array_get (types, i);
-               string_heap_insert_mstring (&assembly->sheap, tb->name, error);
-               if (!is_ok (error))
-                       goto leave_types;
-       }
-
-       for (i = 0; i < mono_ptr_array_size (types); ++i) {
-               MonoReflectionTypeBuilder *type = (MonoReflectionTypeBuilder *)mono_ptr_array_get (types, i);
-               if (!mono_image_get_type_info (domain, type, assembly, error))
-                       goto leave_types;
-       }
-
-       /* 
-        * table->rows is already set above and in mono_image_fill_module_table.
-        */
-       /* add all the custom attributes at the end, once all the indexes are stable */
-       if (!mono_image_add_cattrs (assembly, 1, MONO_CUSTOM_ATTR_ASSEMBLY, assemblyb->cattrs, error))
-               goto leave_types;
-
-       /* CAS assembly permissions */
-       if (assemblyb->permissions_minimum)
-               mono_image_add_decl_security (assembly, mono_metadata_make_token (MONO_TABLE_ASSEMBLY, 1), assemblyb->permissions_minimum);
-       if (assemblyb->permissions_optional)
-               mono_image_add_decl_security (assembly, mono_metadata_make_token (MONO_TABLE_ASSEMBLY, 1), assemblyb->permissions_optional);
-       if (assemblyb->permissions_refused)
-               mono_image_add_decl_security (assembly, mono_metadata_make_token (MONO_TABLE_ASSEMBLY, 1), assemblyb->permissions_refused);
-
-       if (!module_add_cattrs (assembly, moduleb, error))
-               goto leave_types;
-
-       /* fixup tokens */
-       mono_g_hash_table_foreach (assembly->token_fixups, (GHFunc)fixup_method, assembly);
-
-       /* Create the MethodImpl table.  We do this after emitting all methods so we already know
-        * the final tokens and don't need another fixup pass. */
-
-       if (moduleb->global_methods) {
-               for (i = 0; i < mono_array_length (moduleb->global_methods); ++i) {
-                       MonoReflectionMethodBuilder *mb = mono_array_get (
-                               moduleb->global_methods, MonoReflectionMethodBuilder*, i);
-                       if (!mono_image_add_methodimpl (assembly, mb, error))
-                               goto leave_types;
-               }
-       }
-
-       for (i = 0; i < mono_ptr_array_size (types); ++i) {
-               MonoReflectionTypeBuilder *type = (MonoReflectionTypeBuilder *)mono_ptr_array_get (types, i);
-               if (type->methods) {
-                       for (j = 0; j < type->num_methods; ++j) {
-                               MonoReflectionMethodBuilder *mb = mono_array_get (
-                                       type->methods, MonoReflectionMethodBuilder*, j);
-
-                               if (!mono_image_add_methodimpl (assembly, mb, error))
-                                       goto leave_types;
-                       }
-               }
-       }
-
-       fixup_cattrs (assembly);
-
-leave_types:
-       mono_ptr_array_destroy (types);
-leave:
-
-       return mono_error_ok (error);
-}
-
-#else /* DISABLE_REFLECTION_EMIT_SAVE */
-
-gboolean
-mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb, MonoError *error)
-{
-       g_error ("This mono runtime was configured with --enable-minimal=reflection_emit_save, so saving of dynamic assemblies is not supported.");
-}
-
-#endif /* DISABLE_REFLECTION_EMIT_SAVE */
-
-
-typedef struct {
-       guint32 import_lookup_table;
-       guint32 timestamp;
-       guint32 forwarder;
-       guint32 name_rva;
-       guint32 import_address_table_rva;
-} MonoIDT;
-
-typedef struct {
-       guint32 name_rva;
-       guint32 flags;
-} MonoILT;
-
-#ifndef DISABLE_REFLECTION_EMIT
-
-/*
- * mono_image_insert_string:
- * @module: module builder object
- * @str: a string
- *
- * Insert @str into the user string stream of @module.
- */
-guint32
-mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
-{
-       MonoDynamicImage *assembly;
-       guint32 idx;
-       char buf [16];
-       char *b = buf;
-       
-       if (!module->dynamic_image)
-               mono_image_module_basic_init (module);
-
-       assembly = module->dynamic_image;
-       
-       if (assembly->save) {
-               mono_metadata_encode_value (1 | (str->length * 2), b, &b);
-               idx = mono_image_add_stream_data (&assembly->us, buf, b-buf);
-#if G_BYTE_ORDER != G_LITTLE_ENDIAN
-       {
-               char *swapped = g_malloc (2 * mono_string_length (str));
-               const char *p = (const char*)mono_string_chars (str);
-
-               swap_with_size (swapped, p, 2, mono_string_length (str));
-               mono_image_add_stream_data (&assembly->us, swapped, str->length * 2);
-               g_free (swapped);
-       }
-#else
-               mono_image_add_stream_data (&assembly->us, (const char*)mono_string_chars (str), str->length * 2);
-#endif
-               mono_image_add_stream_data (&assembly->us, "", 1);
-       } else {
-               idx = assembly->us.index ++;
-       }
-
-       register_dyn_token (assembly, MONO_TOKEN_STRING | idx, (MonoObject*)str);
-
-       return MONO_TOKEN_STRING | idx;
-}
-
-guint32
-mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types, MonoError *error)
-{
-       MonoClass *klass;
-       guint32 token = 0;
-       MonoMethodSignature *sig;
-
-       mono_error_init (error);
-
-       klass = obj->vtable->klass;
-       if (strcmp (klass->name, "MonoMethod") == 0 || strcmp (klass->name, "MonoCMethod") == 0) {
-               MonoMethod *method = ((MonoReflectionMethod *)obj)->method;
-               MonoMethodSignature *old;
-               guint32 sig_token, parent;
-               int nargs, i;
-
-               g_assert (opt_param_types && (mono_method_signature (method)->sentinelpos >= 0));
-
-               nargs = mono_array_length (opt_param_types);
-               old = mono_method_signature (method);
-               sig = mono_metadata_signature_alloc ( &assembly->image, old->param_count + nargs);
-
-               sig->hasthis = old->hasthis;
-               sig->explicit_this = old->explicit_this;
-               sig->call_convention = old->call_convention;
-               sig->generic_param_count = old->generic_param_count;
-               sig->param_count = old->param_count + nargs;
-               sig->sentinelpos = old->param_count;
-               sig->ret = old->ret;
-
-               for (i = 0; i < old->param_count; i++)
-                       sig->params [i] = old->params [i];
-
-               for (i = 0; i < nargs; i++) {
-                       MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
-                       sig->params [old->param_count + i] = mono_reflection_type_get_handle (rt, error);
-                       if (!is_ok (error)) goto fail;
-               }
-
-               parent = mono_image_typedef_or_ref (assembly, &method->klass->byval_arg);
-               g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_MEMBERREF_PARENT_TYPEREF);
-               parent >>= MONO_TYPEDEFORREF_BITS;
-
-               parent <<= MONO_MEMBERREF_PARENT_BITS;
-               parent |= MONO_MEMBERREF_PARENT_TYPEREF;
-
-               sig_token = method_encode_signature (assembly, sig);
-               token = mono_image_get_varargs_method_token (assembly, parent, method->name, sig_token);
-       } else if (strcmp (klass->name, "MethodBuilder") == 0) {
-               MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
-               ReflectionMethodBuilder rmb;
-               guint32 parent, sig_token;
-               int nopt_args, nparams, ngparams, i;
-
-               if (!reflection_methodbuilder_from_method_builder (&rmb, mb, error))
-                       goto fail;
-               
-               rmb.opt_types = opt_param_types;
-               nopt_args = mono_array_length (opt_param_types);
-
-               nparams = rmb.parameters ? mono_array_length (rmb.parameters): 0;
-               ngparams = rmb.generic_params ? mono_array_length (rmb.generic_params): 0;
-               sig = mono_metadata_signature_alloc (&assembly->image, nparams + nopt_args);
-
-               sig->hasthis = !(rmb.attrs & METHOD_ATTRIBUTE_STATIC);
-               sig->explicit_this = (rmb.call_conv & 0x40) == 0x40;
-               sig->call_convention = rmb.call_conv;
-               sig->generic_param_count = ngparams;
-               sig->param_count = nparams + nopt_args;
-               sig->sentinelpos = nparams;
-               sig->ret = mono_reflection_type_get_handle (rmb.rtype, error);
-               if (!is_ok (error)) goto fail;
-
-               for (i = 0; i < nparams; i++) {
-                       MonoReflectionType *rt = mono_array_get (rmb.parameters, MonoReflectionType *, i);
-                       sig->params [i] = mono_reflection_type_get_handle (rt, error);
-                       if (!is_ok (error)) goto fail;
-               }
-
-               for (i = 0; i < nopt_args; i++) {
-                       MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
-                       sig->params [nparams + i] = mono_reflection_type_get_handle (rt, error);
-                       if (!is_ok (error)) goto fail;
-               }
-
-               sig_token = method_builder_encode_signature (assembly, &rmb, error);
-               if (!is_ok (error))
-                       goto fail;
-
-               parent = mono_image_create_token (assembly, obj, TRUE, TRUE, error);
-               if (!mono_error_ok (error))
-                       goto fail;
-               g_assert (mono_metadata_token_table (parent) == MONO_TABLE_METHOD);
-
-               parent = mono_metadata_token_index (parent) << MONO_MEMBERREF_PARENT_BITS;
-               parent |= MONO_MEMBERREF_PARENT_METHODDEF;
-
-               char *name = mono_string_to_utf8_checked (rmb.name, error);
-               if (!is_ok (error)) goto fail;
-               token = mono_image_get_varargs_method_token (
-                       assembly, parent, name, sig_token);
-               g_free (name);
-       } else {
-               g_error ("requested method token for %s\n", klass->name);
-       }
-
-       g_hash_table_insert (assembly->vararg_aux_hash, GUINT_TO_POINTER (token), sig);
-       register_dyn_token (assembly, token, obj);
-       return token;
-fail:
-       g_assert (!mono_error_ok (error));
-       return 0;
-}
-
-/*
- * mono_image_create_token:
- * @assembly: a dynamic assembly
- * @obj:
- * @register_token: Whenever to register the token in the assembly->tokens hash. 
- *
- * Get a token to insert in the IL code stream for the given MemberInfo.
- * The metadata emission routines need to pass FALSE as REGISTER_TOKEN, since by that time, 
- * the table_idx-es were recomputed, so registering the token would overwrite an existing 
- * entry.
- */
-guint32
-mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, 
-                        gboolean create_open_instance, gboolean register_token,
-                        MonoError *error)
-{
-       MonoClass *klass;
-       guint32 token = 0;
-
-       mono_error_init (error);
-
-       klass = obj->vtable->klass;
-
-       /* Check for user defined reflection objects */
-       /* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
-       if (klass->image != mono_defaults.corlib || (strcmp (klass->name, "TypeDelegator") == 0)) {
-               mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported");
-               return 0;
-       }
-
-       if (strcmp (klass->name, "MethodBuilder") == 0) {
-               MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
-               MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
-
-               if (tb->module->dynamic_image == assembly && !tb->generic_params && !mb->generic_params)
-                       token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
-               else {
-                       token = mono_image_get_methodbuilder_token (assembly, mb, create_open_instance, error);
-                       if (!mono_error_ok (error))
-                               return 0;
-               }
-               /*g_print ("got token 0x%08x for %s\n", token, mono_string_to_utf8 (mb->name));*/
-       } else if (strcmp (klass->name, "ConstructorBuilder") == 0) {
-               MonoReflectionCtorBuilder *mb = (MonoReflectionCtorBuilder *)obj;
-               MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
-
-               if (tb->module->dynamic_image == assembly && !tb->generic_params)
-                       token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
-               else {
-                       token = mono_image_get_ctorbuilder_token (assembly, mb, error);
-                       if (!mono_error_ok (error))
-                               return 0;
-               }
-               /*g_print ("got token 0x%08x for %s\n", token, mono_string_to_utf8 (mb->name));*/
-       } else if (strcmp (klass->name, "FieldBuilder") == 0) {
-               MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)obj;
-               MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)fb->typeb;
-               if (tb->generic_params) {
-                       token = mono_image_get_generic_field_token (assembly, fb, error);
-                       return_val_if_nok (error, 0);
-               } else {
-                       if (tb->module->dynamic_image == assembly) {
-                               token = fb->table_idx | MONO_TOKEN_FIELD_DEF;
-                       } else {
-                               token = mono_image_get_fieldref_token (assembly, (MonoObject*)fb, fb->handle);
-                       }
-               }
-       } else if (strcmp (klass->name, "TypeBuilder") == 0) {
-               MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)obj;
-               if (create_open_instance && tb->generic_params) {
-                       MonoType *type;
-                       init_type_builder_generics (obj, error);
-                       return_val_if_nok (error, 0);
-                       type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
-                       return_val_if_nok (error, 0);
-                       token = mono_image_typedef_or_ref_full (assembly, type, TRUE);
-                       token = mono_metadata_token_from_dor (token);
-               } else if (tb->module->dynamic_image == assembly) {
-                       token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
-               } else {
-                       MonoType *type;
-                       type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
-                       return_val_if_nok (error, 0);
-                       token = mono_metadata_token_from_dor (mono_image_typedef_or_ref (assembly, type));
-               }
-       } else if (strcmp (klass->name, "RuntimeType") == 0) {
-               MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
-               return_val_if_nok (error, 0);
-               MonoClass *mc = mono_class_from_mono_type (type);
-               token = mono_metadata_token_from_dor (
-                       mono_image_typedef_or_ref_full (assembly, type, mc->generic_container == NULL || create_open_instance));
-       } else if (strcmp (klass->name, "GenericTypeParameterBuilder") == 0) {
-               MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
-               return_val_if_nok (error, 0);
-               token = mono_metadata_token_from_dor (
-                       mono_image_typedef_or_ref (assembly, type));
-       } else if (strcmp (klass->name, "MonoGenericClass") == 0) {
-               MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
-               return_val_if_nok (error, 0);
-               token = mono_metadata_token_from_dor (
-                       mono_image_typedef_or_ref (assembly, type));
-       } else if (strcmp (klass->name, "MonoCMethod") == 0 ||
-                  strcmp (klass->name, "MonoMethod") == 0 ||
-                  strcmp (klass->name, "MonoGenericMethod") == 0 ||
-                  strcmp (klass->name, "MonoGenericCMethod") == 0) {
-               MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
-               if (m->method->is_inflated) {
-                       if (create_open_instance)
-                               token = mono_image_get_methodspec_token (assembly, m->method);
-                       else
-                               token = mono_image_get_inflated_method_token (assembly, m->method);
-               } else if ((m->method->klass->image == &assembly->image) &&
-                        !m->method->klass->generic_class) {
-                       static guint32 method_table_idx = 0xffffff;
-                       if (m->method->klass->wastypebuilder) {
-                               /* we use the same token as the one that was assigned
-                                * to the Methodbuilder.
-                                * FIXME: do the equivalent for Fields.
-                                */
-                               token = m->method->token;
-                       } else {
-                               /*
-                                * Each token should have a unique index, but the indexes are
-                                * assigned by managed code, so we don't know about them. An
-                                * easy solution is to count backwards...
-                                */
-                               method_table_idx --;
-                               token = MONO_TOKEN_METHOD_DEF | method_table_idx;
-                       }
-               } else {
-                       token = mono_image_get_methodref_token (assembly, m->method, create_open_instance);
-               }
-               /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
-       } else if (strcmp (klass->name, "MonoField") == 0) {
-               MonoReflectionField *f = (MonoReflectionField *)obj;
-               if ((f->field->parent->image == &assembly->image) && !is_field_on_inst (f->field)) {
-                       static guint32 field_table_idx = 0xffffff;
-                       field_table_idx --;
-                       token = MONO_TOKEN_FIELD_DEF | field_table_idx;
-               } else {
-                       token = mono_image_get_fieldref_token (assembly, (MonoObject*)f, f->field);
-               }
-               /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
-       } else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
-               MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod *)obj;
-               token = mono_image_get_array_token (assembly, m, error);
-               return_val_if_nok (error, 0);
-       } else if (strcmp (klass->name, "SignatureHelper") == 0) {
-               MonoReflectionSigHelper *s = (MonoReflectionSigHelper*)obj;
-               token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s, error);
-               return_val_if_nok (error, 0);
-       } else if (strcmp (klass->name, "EnumBuilder") == 0) {
-               MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
-               return_val_if_nok (error, 0);
-               token = mono_metadata_token_from_dor (
-                       mono_image_typedef_or_ref (assembly, type));
-       } else if (strcmp (klass->name, "FieldOnTypeBuilderInst") == 0) {
-               MonoReflectionFieldOnTypeBuilderInst *f = (MonoReflectionFieldOnTypeBuilderInst*)obj;
-               token = mono_image_get_field_on_inst_token (assembly, f, error);
-               return_val_if_nok (error, 0);
-       } else if (strcmp (klass->name, "ConstructorOnTypeBuilderInst") == 0) {
-               MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj;
-               token = mono_image_get_ctor_on_inst_token (assembly, c, create_open_instance, error);
-               if (!mono_error_ok (error))
-                       return 0;
-       } else if (strcmp (klass->name, "MethodOnTypeBuilderInst") == 0) {
-               MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
-               token = mono_image_get_method_on_inst_token (assembly, m, create_open_instance, error);
-               if (!mono_error_ok (error))
-                       return 0;
-       } else if (is_sre_array (klass) || is_sre_byref (klass) || is_sre_pointer (klass)) {
-               MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
-               return_val_if_nok (error, 0);
-               token = mono_metadata_token_from_dor (
-                               mono_image_typedef_or_ref (assembly, type));
-       } else {
-               g_error ("requested token for %s\n", klass->name);
-       }
-
-       if (register_token)
-               mono_image_register_token (assembly, token, obj);
-
-       return token;
-}
-
-/*
- * mono_image_register_token:
- *
- *   Register the TOKEN->OBJ mapping in the mapping table in ASSEMBLY. This is required for
- * the Module.ResolveXXXToken () methods to work.
- */
-void
-mono_image_register_token (MonoDynamicImage *assembly, guint32 token, MonoObject *obj)
-{
-       MonoObject *prev;
-
-       dynamic_image_lock (assembly);
-       prev = (MonoObject *)mono_g_hash_table_lookup (assembly->tokens, GUINT_TO_POINTER (token));
-       if (prev) {
-               /* There could be multiple MethodInfo objects with the same token */
-               //g_assert (prev == obj);
-       } else {
-               mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), obj);
-       }
-       dynamic_image_unlock (assembly);
-}
-
-static MonoDynamicImage*
-create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, char *module_name)
-{
-       static const guchar entrycode [16] = {0xff, 0x25, 0};
-       MonoDynamicImage *image;
-       int i;
-
-       const char *version;
-
-       if (!strcmp (mono_get_runtime_info ()->framework_version, "2.1"))
-               version = "v2.0.50727"; /* HACK: SL 2 enforces the .net 2 metadata version */
-       else
-               version = mono_get_runtime_info ()->runtime_version;
-
-#if HAVE_BOEHM_GC
-       /* The MonoGHashTable's need GC tracking */
-       image = (MonoDynamicImage *)GC_MALLOC (sizeof (MonoDynamicImage));
-#else
-       image = g_new0 (MonoDynamicImage, 1);
-#endif
-
-       mono_profiler_module_event (&image->image, MONO_PROFILE_START_LOAD);
-       
-       /*g_print ("created image %p\n", image);*/
-       /* keep in sync with image.c */
-       image->image.name = assembly_name;
-       image->image.assembly_name = image->image.name; /* they may be different */
-       image->image.module_name = module_name;
-       image->image.version = g_strdup (version);
-       image->image.md_version_major = 1;
-       image->image.md_version_minor = 1;
-       image->image.dynamic = TRUE;
-
-       image->image.references = g_new0 (MonoAssembly*, 1);
-       image->image.references [0] = NULL;
-
-       mono_image_init (&image->image);
-
-       image->token_fixups = mono_g_hash_table_new_type ((GHashFunc)mono_object_hash, NULL, MONO_HASH_KEY_GC, MONO_ROOT_SOURCE_REFLECTION, "dynamic module token fixups table");
-       image->method_to_table_idx = g_hash_table_new (NULL, NULL);
-       image->field_to_table_idx = g_hash_table_new (NULL, NULL);
-       image->method_aux_hash = g_hash_table_new (NULL, NULL);
-       image->vararg_aux_hash = g_hash_table_new (NULL, NULL);
-       image->handleref = g_hash_table_new (NULL, NULL);
-       image->handleref_managed = mono_g_hash_table_new_type ((GHashFunc)mono_object_hash, NULL, MONO_HASH_KEY_GC, MONO_ROOT_SOURCE_REFLECTION, "dynamic module reference-to-token table");
-       image->tokens = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_REFLECTION, "dynamic module tokens table");
-       image->generic_def_objects = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_REFLECTION, "dynamic module generic definitions table");
-       image->methodspec = mono_g_hash_table_new_type ((GHashFunc)mono_object_hash, NULL, MONO_HASH_KEY_GC, MONO_ROOT_SOURCE_REFLECTION, "dynamic module method specifications table");
-       image->typespec = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal);
-       image->typeref = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal);
-       image->blob_cache = g_hash_table_new ((GHashFunc)mono_blob_entry_hash, (GCompareFunc)mono_blob_entry_equal);
-       image->gen_params = g_ptr_array_new ();
-       image->remapped_tokens = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_REFLECTION, "dynamic module remapped tokens table");
-
-       /*g_print ("string heap create for image %p (%s)\n", image, module_name);*/
-       string_heap_init (&image->sheap);
-       mono_image_add_stream_data (&image->us, "", 1);
-       add_to_blob_cached (image, (char*) "", 1, NULL, 0);
-       /* import tables... */
-       mono_image_add_stream_data (&image->code, (char*)entrycode, sizeof (entrycode));
-       image->iat_offset = mono_image_add_stream_zero (&image->code, 8); /* two IAT entries */
-       image->idt_offset = mono_image_add_stream_zero (&image->code, 2 * sizeof (MonoIDT)); /* two IDT entries */
-       image->imp_names_offset = mono_image_add_stream_zero (&image->code, 2); /* flags for name entry */
-       mono_image_add_stream_data (&image->code, "_CorExeMain", 12);
-       mono_image_add_stream_data (&image->code, "mscoree.dll", 12);
-       image->ilt_offset = mono_image_add_stream_zero (&image->code, 8); /* two ILT entries */
-       stream_data_align (&image->code);
-
-       image->cli_header_offset = mono_image_add_stream_zero (&image->code, sizeof (MonoCLIHeader));
-
-       for (i=0; i < MONO_TABLE_NUM; ++i) {
-               image->tables [i].next_idx = 1;
-               image->tables [i].columns = table_sizes [i];
-       }
-
-       image->image.assembly = (MonoAssembly*)assembly;
-       image->run = assembly->run;
-       image->save = assembly->save;
-       image->pe_kind = 0x1; /* ILOnly */
-       image->machine = 0x14c; /* I386 */
-       
-       mono_profiler_module_loaded (&image->image, MONO_PROFILE_OK);
-
-       dynamic_images_lock ();
-
-       if (!dynamic_images)
-               dynamic_images = g_ptr_array_new ();
-
-       g_ptr_array_add (dynamic_images, image);
-
-       dynamic_images_unlock ();
-
-       return image;
-}
-#endif
-
-static void
-free_blob_cache_entry (gpointer key, gpointer val, gpointer user_data)
-{
-       g_free (key);
-}
-
-static void
-release_hashtable (MonoGHashTable **hash)
-{
-       if (*hash) {
-               mono_g_hash_table_destroy (*hash);
-               *hash = NULL;
-       }
-}
-
-void
-mono_dynamic_image_release_gc_roots (MonoDynamicImage *image)
-{
-       release_hashtable (&image->token_fixups);
-       release_hashtable (&image->handleref_managed);
-       release_hashtable (&image->tokens);
-       release_hashtable (&image->remapped_tokens);
-       release_hashtable (&image->generic_def_objects);
-       release_hashtable (&image->methodspec);
-}
-
-// Free dynamic image pass one: Free resources but not image itself
-void
-mono_dynamic_image_free (MonoDynamicImage *image)
-{
-       MonoDynamicImage *di = image;
-       GList *list;
-       int i;
-
-       if (di->methodspec)
-               mono_g_hash_table_destroy (di->methodspec);
-       if (di->typespec)
-               g_hash_table_destroy (di->typespec);
-       if (di->typeref)
-               g_hash_table_destroy (di->typeref);
-       if (di->handleref)
-               g_hash_table_destroy (di->handleref);
-       if (di->handleref_managed)
-               mono_g_hash_table_destroy (di->handleref_managed);
-       if (di->tokens)
-               mono_g_hash_table_destroy (di->tokens);
-       if (di->remapped_tokens)
-               mono_g_hash_table_destroy (di->remapped_tokens);
-       if (di->generic_def_objects)
-               mono_g_hash_table_destroy (di->generic_def_objects);
-       if (di->blob_cache) {
-               g_hash_table_foreach (di->blob_cache, free_blob_cache_entry, NULL);
-               g_hash_table_destroy (di->blob_cache);
-       }
-       if (di->standalonesig_cache)
-               g_hash_table_destroy (di->standalonesig_cache);
-       for (list = di->array_methods; list; list = list->next) {
-               ArrayMethod *am = (ArrayMethod *)list->data;
-               g_free (am->sig);
-               g_free (am->name);
-               g_free (am);
-       }
-       g_list_free (di->array_methods);
-       if (di->gen_params) {
-               for (i = 0; i < di->gen_params->len; i++) {
-                       GenericParamTableEntry *entry = (GenericParamTableEntry *)g_ptr_array_index (di->gen_params, i);
-                       mono_gc_deregister_root ((char*) &entry->gparam);
-                       g_free (entry);
-               }
-               g_ptr_array_free (di->gen_params, TRUE);
-       }
-       if (di->token_fixups)
-               mono_g_hash_table_destroy (di->token_fixups);
-       if (di->method_to_table_idx)
-               g_hash_table_destroy (di->method_to_table_idx);
-       if (di->field_to_table_idx)
-               g_hash_table_destroy (di->field_to_table_idx);
-       if (di->method_aux_hash)
-               g_hash_table_destroy (di->method_aux_hash);
-       if (di->vararg_aux_hash)
-               g_hash_table_destroy (di->vararg_aux_hash);
-       g_free (di->strong_name);
-       g_free (di->win32_res);
-       if (di->public_key)
-               g_free (di->public_key);
-
-       /*g_print ("string heap destroy for image %p\n", di);*/
-       mono_dynamic_stream_reset (&di->sheap);
-       mono_dynamic_stream_reset (&di->code);
-       mono_dynamic_stream_reset (&di->resources);
-       mono_dynamic_stream_reset (&di->us);
-       mono_dynamic_stream_reset (&di->blob);
-       mono_dynamic_stream_reset (&di->tstream);
-       mono_dynamic_stream_reset (&di->guid);
-       for (i = 0; i < MONO_TABLE_NUM; ++i) {
-               g_free (di->tables [i].values);
-       }
-
-       dynamic_images_lock ();
-
-       if (dynamic_images)
-               g_ptr_array_remove (dynamic_images, di);
-
-       dynamic_images_unlock ();
-}
-
-// Free dynamic image pass two: Free image itself (might never get called in some debug modes)
-void
-mono_dynamic_image_free_image (MonoDynamicImage *image)
-{
-       /* See create_dynamic_mono_image () */
-#if HAVE_BOEHM_GC
-       /* Allocated using GC_MALLOC */
-#else
-       g_free (image);
-#endif
-}
-
-#ifndef DISABLE_REFLECTION_EMIT
-
-/*
- * mono_image_basic_init:
- * @assembly: an assembly builder object
- *
- * Create the MonoImage that represents the assembly builder and setup some
- * of the helper hash table and the basic metadata streams.
- */
-static void
-mono_image_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
-{
-       MonoError error;
-       MonoDynamicAssembly *assembly;
-       MonoDynamicImage *image;
-       MonoDomain *domain = mono_object_domain (assemblyb);
-       
-       if (assemblyb->dynamic_assembly)
-               return;
-
-#if HAVE_BOEHM_GC
-       /* assembly->assembly.image might be GC allocated */
-       assembly = assemblyb->dynamic_assembly = (MonoDynamicAssembly *)GC_MALLOC (sizeof (MonoDynamicAssembly));
-#else
-       assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
-#endif
-
-       mono_profiler_assembly_event (&assembly->assembly, MONO_PROFILE_START_LOAD);
-       
-       assembly->assembly.ref_count = 1;
-       assembly->assembly.dynamic = TRUE;
-       assembly->assembly.corlib_internal = assemblyb->corlib_internal;
-       assemblyb->assembly.assembly = (MonoAssembly*)assembly;
-       assembly->assembly.basedir = mono_string_to_utf8_checked (assemblyb->dir, &error);
-       if (mono_error_set_pending_exception (&error))
-               return;
-       if (assemblyb->culture) {
-               assembly->assembly.aname.culture = mono_string_to_utf8_checked (assemblyb->culture, &error);
-               if (mono_error_set_pending_exception (&error))
-                       return;
-       } else
-               assembly->assembly.aname.culture = g_strdup ("");
-
-        if (assemblyb->version) {
-                       char *vstr = mono_string_to_utf8_checked (assemblyb->version, &error);
-                       if (mono_error_set_pending_exception (&error))
-                               return;
-                       char **version = g_strsplit (vstr, ".", 4);
-                       char **parts = version;
-                       assembly->assembly.aname.major = atoi (*parts++);
-                       assembly->assembly.aname.minor = atoi (*parts++);
-                       assembly->assembly.aname.build = *parts != NULL ? atoi (*parts++) : 0;
-                       assembly->assembly.aname.revision = *parts != NULL ? atoi (*parts) : 0;
-
-                       g_strfreev (version);
-                       g_free (vstr);
-        } else {
-                       assembly->assembly.aname.major = 0;
-                       assembly->assembly.aname.minor = 0;
-                       assembly->assembly.aname.build = 0;
-                       assembly->assembly.aname.revision = 0;
-        }
-
-       assembly->run = assemblyb->access != 2;
-       assembly->save = assemblyb->access != 1;
-       assembly->domain = domain;
-
-       char *assembly_name = mono_string_to_utf8_checked (assemblyb->name, &error);
-       if (mono_error_set_pending_exception (&error))
-               return;
-       image = create_dynamic_mono_image (assembly, assembly_name, g_strdup ("RefEmit_YouForgotToDefineAModule"));
-       image->initial_image = TRUE;
-       assembly->assembly.aname.name = image->image.name;
-       assembly->assembly.image = &image->image;
-       if (assemblyb->pktoken && assemblyb->pktoken->max_length) {
-               /* -1 to correct for the trailing NULL byte */
-               if (assemblyb->pktoken->max_length != MONO_PUBLIC_KEY_TOKEN_LENGTH - 1) {
-                       g_error ("Public key token length invalid for assembly %s: %i", assembly->assembly.aname.name, assemblyb->pktoken->max_length);
-               }
-               memcpy (&assembly->assembly.aname.public_key_token, mono_array_addr (assemblyb->pktoken, guint8, 0), assemblyb->pktoken->max_length);           
-       }
-
-       mono_domain_assemblies_lock (domain);
-       domain->domain_assemblies = g_slist_append (domain->domain_assemblies, assembly);
-       mono_domain_assemblies_unlock (domain);
-
-       register_assembly (mono_object_domain (assemblyb), &assemblyb->assembly, &assembly->assembly);
-       
-       mono_profiler_assembly_loaded (&assembly->assembly, MONO_PROFILE_OK);
-       
-       mono_assembly_invoke_load_hook ((MonoAssembly*)assembly);
-}
-
-#endif /* !DISABLE_REFLECTION_EMIT */
-
-#ifndef DISABLE_REFLECTION_EMIT_SAVE
-
-static int
-calc_section_size (MonoDynamicImage *assembly)
-{
-       int nsections = 0;
-
-       /* alignment constraints */
-       mono_image_add_stream_zero (&assembly->code, 4 - (assembly->code.index % 4));
-       g_assert ((assembly->code.index % 4) == 0);
-       assembly->meta_size += 3;
-       assembly->meta_size &= ~3;
-       mono_image_add_stream_zero (&assembly->resources, 4 - (assembly->resources.index % 4));
-       g_assert ((assembly->resources.index % 4) == 0);
-
-       assembly->sections [MONO_SECTION_TEXT].size = assembly->meta_size + assembly->code.index + assembly->resources.index + assembly->strong_name_size;
-       assembly->sections [MONO_SECTION_TEXT].attrs = SECT_FLAGS_HAS_CODE | SECT_FLAGS_MEM_EXECUTE | SECT_FLAGS_MEM_READ;
-       nsections++;
-
-       if (assembly->win32_res) {
-               guint32 res_size = (assembly->win32_res_size + 3) & ~3;
-
-               assembly->sections [MONO_SECTION_RSRC].size = res_size;
-               assembly->sections [MONO_SECTION_RSRC].attrs = SECT_FLAGS_HAS_INITIALIZED_DATA | SECT_FLAGS_MEM_READ;
-               nsections++;
-       }
-
-       assembly->sections [MONO_SECTION_RELOC].size = 12;
-       assembly->sections [MONO_SECTION_RELOC].attrs = SECT_FLAGS_MEM_READ | SECT_FLAGS_MEM_DISCARDABLE | SECT_FLAGS_HAS_INITIALIZED_DATA;
-       nsections++;
-
-       return nsections;
-}
-
-typedef struct {
-       guint32 id;
-       guint32 offset;
-       GSList *children;
-       MonoReflectionWin32Resource *win32_res; /* Only for leaf nodes */
-} ResTreeNode;
-
-static int
-resource_tree_compare_by_id (gconstpointer a, gconstpointer b)
-{
-       ResTreeNode *t1 = (ResTreeNode*)a;
-       ResTreeNode *t2 = (ResTreeNode*)b;
-
-       return t1->id - t2->id;
-}
-
-/*
- * resource_tree_create:
- *
- *  Organize the resources into a resource tree.
- */
-static ResTreeNode *
-resource_tree_create (MonoArray *win32_resources)
-{
-       ResTreeNode *tree, *res_node, *type_node, *lang_node;
-       GSList *l;
-       int i;
-
-       tree = g_new0 (ResTreeNode, 1);
-       
-       for (i = 0; i < mono_array_length (win32_resources); ++i) {
-               MonoReflectionWin32Resource *win32_res =
-                       (MonoReflectionWin32Resource*)mono_array_addr (win32_resources, MonoReflectionWin32Resource, i);
-
-               /* Create node */
-
-               /* FIXME: BUG: this stores managed references in unmanaged memory */
-               lang_node = g_new0 (ResTreeNode, 1);
-               lang_node->id = win32_res->lang_id;
-               lang_node->win32_res = win32_res;
-
-               /* Create type node if neccesary */
-               type_node = NULL;
-               for (l = tree->children; l; l = l->next)
-                       if (((ResTreeNode*)(l->data))->id == win32_res->res_type) {
-                               type_node = (ResTreeNode*)l->data;
-                               break;
-                       }
-
-               if (!type_node) {
-                       type_node = g_new0 (ResTreeNode, 1);
-                       type_node->id = win32_res->res_type;
-
-                       /* 
-                        * The resource types have to be sorted otherwise
-                        * Windows Explorer can't display the version information.
-                        */
-                       tree->children = g_slist_insert_sorted (tree->children, 
-                               type_node, resource_tree_compare_by_id);
-               }
-
-               /* Create res node if neccesary */
-               res_node = NULL;
-               for (l = type_node->children; l; l = l->next)
-                       if (((ResTreeNode*)(l->data))->id == win32_res->res_id) {
-                               res_node = (ResTreeNode*)l->data;
-                               break;
-                       }
-
-               if (!res_node) {
-                       res_node = g_new0 (ResTreeNode, 1);
-                       res_node->id = win32_res->res_id;
-                       type_node->children = g_slist_append (type_node->children, res_node);
-               }
-
-               res_node->children = g_slist_append (res_node->children, lang_node);
-       }
-
-       return tree;
-}
-
-/*
- * resource_tree_encode:
- * 
- *   Encode the resource tree into the format used in the PE file.
- */
-static void
-resource_tree_encode (ResTreeNode *node, char *begin, char *p, char **endbuf)
-{
-       char *entries;
-       MonoPEResourceDir dir;
-       MonoPEResourceDirEntry dir_entry;
-       MonoPEResourceDataEntry data_entry;
-       GSList *l;
-       guint32 res_id_entries;
-
-       /*
-        * For the format of the resource directory, see the article
-        * "An In-Depth Look into the Win32 Portable Executable File Format" by
-        * Matt Pietrek
-        */
-
-       memset (&dir, 0, sizeof (dir));
-       memset (&dir_entry, 0, sizeof (dir_entry));
-       memset (&data_entry, 0, sizeof (data_entry));
-
-       g_assert (sizeof (dir) == 16);
-       g_assert (sizeof (dir_entry) == 8);
-       g_assert (sizeof (data_entry) == 16);
-
-       node->offset = p - begin;
-
-       /* IMAGE_RESOURCE_DIRECTORY */
-       res_id_entries = g_slist_length (node->children);
-       dir.res_id_entries = GUINT16_TO_LE (res_id_entries);
-
-       memcpy (p, &dir, sizeof (dir));
-       p += sizeof (dir);
-
-       /* Reserve space for entries */
-       entries = p;
-       p += sizeof (dir_entry) * res_id_entries;
-
-       /* Write children */
-       for (l = node->children; l; l = l->next) {
-               ResTreeNode *child = (ResTreeNode*)l->data;
-
-               if (child->win32_res) {
-                       guint32 size;
-
-                       child->offset = p - begin;
-
-                       /* IMAGE_RESOURCE_DATA_ENTRY */
-                       data_entry.rde_data_offset = GUINT32_TO_LE (p - begin + sizeof (data_entry));
-                       size = mono_array_length (child->win32_res->res_data);
-                       data_entry.rde_size = GUINT32_TO_LE (size);
-
-                       memcpy (p, &data_entry, sizeof (data_entry));
-                       p += sizeof (data_entry);
-
-                       memcpy (p, mono_array_addr (child->win32_res->res_data, char, 0), size);
-                       p += size;
-               } else {
-                       resource_tree_encode (child, begin, p, &p);
-               }
-       }
-
-       /* IMAGE_RESOURCE_ENTRY */
-       for (l = node->children; l; l = l->next) {
-               ResTreeNode *child = (ResTreeNode*)l->data;
-
-               MONO_PE_RES_DIR_ENTRY_SET_NAME (dir_entry, FALSE, child->id);
-               MONO_PE_RES_DIR_ENTRY_SET_DIR (dir_entry, !child->win32_res, child->offset);
-
-               memcpy (entries, &dir_entry, sizeof (dir_entry));
-               entries += sizeof (dir_entry);
-       }
-
-       *endbuf = p;
-}
-
-static void
-resource_tree_free (ResTreeNode * node)
-{
-       GSList * list;
-       for (list = node->children; list; list = list->next)
-               resource_tree_free ((ResTreeNode*)list->data);
-       g_slist_free(node->children);
-       g_free (node);
-}
-
-static void
-assembly_add_win32_resources (MonoDynamicImage *assembly, MonoReflectionAssemblyBuilder *assemblyb)
-{
-       char *buf;
-       char *p;
-       guint32 size, i;
-       MonoReflectionWin32Resource *win32_res;
-       ResTreeNode *tree;
-
-       if (!assemblyb->win32_resources)
-               return;
-
-       /*
-        * Resources are stored in a three level tree inside the PE file.
-        * - level one contains a node for each type of resource
-        * - level two contains a node for each resource
-        * - level three contains a node for each instance of a resource for a
-        *   specific language.
-        */
-
-       tree = resource_tree_create (assemblyb->win32_resources);
-
-       /* Estimate the size of the encoded tree */
-       size = 0;
-       for (i = 0; i < mono_array_length (assemblyb->win32_resources); ++i) {
-               win32_res = (MonoReflectionWin32Resource*)mono_array_addr (assemblyb->win32_resources, MonoReflectionWin32Resource, i);
-               size += mono_array_length (win32_res->res_data);
-       }
-       /* Directory structure */
-       size += mono_array_length (assemblyb->win32_resources) * 256;
-       p = buf = (char *)g_malloc (size);
-
-       resource_tree_encode (tree, p, p, &p);
-
-       g_assert (p - buf <= size);
-
-       assembly->win32_res = (char *)g_malloc (p - buf);
-       assembly->win32_res_size = p - buf;
-       memcpy (assembly->win32_res, buf, p - buf);
-
-       g_free (buf);
-       resource_tree_free (tree);
-}
-
-static void
-fixup_resource_directory (char *res_section, char *p, guint32 rva)
-{
-       MonoPEResourceDir *dir = (MonoPEResourceDir*)p;
-       int i;
-
-       p += sizeof (MonoPEResourceDir);
-       for (i = 0; i < GUINT16_FROM_LE (dir->res_named_entries) + GUINT16_FROM_LE (dir->res_id_entries); ++i) {
-               MonoPEResourceDirEntry *dir_entry = (MonoPEResourceDirEntry*)p;
-               char *child = res_section + MONO_PE_RES_DIR_ENTRY_DIR_OFFSET (*dir_entry);
-               if (MONO_PE_RES_DIR_ENTRY_IS_DIR (*dir_entry)) {
-                       fixup_resource_directory (res_section, child, rva);
-               } else {
-                       MonoPEResourceDataEntry *data_entry = (MonoPEResourceDataEntry*)child;
-                       data_entry->rde_data_offset = GUINT32_TO_LE (GUINT32_FROM_LE (data_entry->rde_data_offset) + rva);
-               }
-
-               p += sizeof (MonoPEResourceDirEntry);
-       }
-}
-
-static void
-checked_write_file (HANDLE f, gconstpointer buffer, guint32 numbytes)
-{
-       guint32 dummy;
-       if (!WriteFile (f, buffer, numbytes, &dummy, NULL))
-               g_error ("WriteFile returned %d\n", GetLastError ());
-}
-
-/*
- * mono_image_create_pefile:
- * @mb: a module builder object
- * 
- * This function creates the PE-COFF header, the image sections, the CLI header  * etc. all the data is written in
- * assembly->pefile where it can be easily retrieved later in chunks.
- */
-gboolean
-mono_image_create_pefile (MonoReflectionModuleBuilder *mb, HANDLE file, MonoError *error)
-{
-       MonoMSDOSHeader *msdos;
-       MonoDotNetHeader *header;
-       MonoSectionTable *section;
-       MonoCLIHeader *cli_header;
-       guint32 size, image_size, virtual_base, text_offset;
-       guint32 header_start, section_start, file_offset, virtual_offset;
-       MonoDynamicImage *assembly;
-       MonoReflectionAssemblyBuilder *assemblyb;
-       MonoDynamicStream pefile_stream = {0};
-       MonoDynamicStream *pefile = &pefile_stream;
-       int i, nsections;
-       guint32 *rva, value;
-       guchar *p;
-       static const unsigned char msheader[] = {
-               0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00,  0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
-               0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
-               0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd,  0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68,
-               0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72,  0x61, 0x6d, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f,
-               0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6e,  0x20, 0x69, 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20,
-               0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a,  0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-       };
-
-       mono_error_init (error);
-
-       assemblyb = mb->assemblyb;
-
-       mono_image_basic_init (assemblyb);
-       assembly = mb->dynamic_image;
-
-       assembly->pe_kind = assemblyb->pe_kind;
-       assembly->machine = assemblyb->machine;
-       ((MonoDynamicImage*)assemblyb->dynamic_assembly->assembly.image)->pe_kind = assemblyb->pe_kind;
-       ((MonoDynamicImage*)assemblyb->dynamic_assembly->assembly.image)->machine = assemblyb->machine;
-       
-       if (!mono_image_build_metadata (mb, error))
-               return FALSE;
-       
-
-       if (mb->is_main && assemblyb->resources) {
-               int len = mono_array_length (assemblyb->resources);
-               for (i = 0; i < len; ++i) {
-                       if (!assembly_add_resource (mb, assembly, (MonoReflectionResource*)mono_array_addr (assemblyb->resources, MonoReflectionResource, i), error))
-                               return FALSE;
-               }
-       }
-
-       if (mb->resources) {
-               int len = mono_array_length (mb->resources);
-               for (i = 0; i < len; ++i) {
-                       if (!assembly_add_resource (mb, assembly, (MonoReflectionResource*)mono_array_addr (mb->resources, MonoReflectionResource, i), error))
-                               return FALSE;
-               }
-       }
-
-       if (!build_compressed_metadata (assembly, error))
-               return FALSE;
-
-       if (mb->is_main)
-               assembly_add_win32_resources (assembly, assemblyb);
-
-       nsections = calc_section_size (assembly);
-       
-       /* The DOS header and stub */
-       g_assert (sizeof (MonoMSDOSHeader) == sizeof (msheader));
-       mono_image_add_stream_data (pefile, (char*)msheader, sizeof (msheader));
-
-       /* the dotnet header */
-       header_start = mono_image_add_stream_zero (pefile, sizeof (MonoDotNetHeader));
-
-       /* the section tables */
-       section_start = mono_image_add_stream_zero (pefile, sizeof (MonoSectionTable) * nsections);
-
-       file_offset = section_start + sizeof (MonoSectionTable) * nsections;
-       virtual_offset = VIRT_ALIGN;
-       image_size = 0;
-
-       for (i = 0; i < MONO_SECTION_MAX; ++i) {
-               if (!assembly->sections [i].size)
-                       continue;
-               /* align offsets */
-               file_offset += FILE_ALIGN - 1;
-               file_offset &= ~(FILE_ALIGN - 1);
-               virtual_offset += VIRT_ALIGN - 1;
-               virtual_offset &= ~(VIRT_ALIGN - 1);
-
-               assembly->sections [i].offset = file_offset;
-               assembly->sections [i].rva = virtual_offset;
-
-               file_offset += assembly->sections [i].size;
-               virtual_offset += assembly->sections [i].size;
-               image_size += (assembly->sections [i].size + VIRT_ALIGN - 1) & ~(VIRT_ALIGN - 1);
-       }
-
-       file_offset += FILE_ALIGN - 1;
-       file_offset &= ~(FILE_ALIGN - 1);
-
-       image_size += section_start + sizeof (MonoSectionTable) * nsections;
-
-       /* back-patch info */
-       msdos = (MonoMSDOSHeader*)pefile->data;
-       msdos->pe_offset = GUINT32_FROM_LE (sizeof (MonoMSDOSHeader));
-
-       header = (MonoDotNetHeader*)(pefile->data + header_start);
-       header->pesig [0] = 'P';
-       header->pesig [1] = 'E';
-       
-       header->coff.coff_machine = GUINT16_FROM_LE (assemblyb->machine);
-       header->coff.coff_sections = GUINT16_FROM_LE (nsections);
-       header->coff.coff_time = GUINT32_FROM_LE (time (NULL));
-       header->coff.coff_opt_header_size = GUINT16_FROM_LE (sizeof (MonoDotNetHeader) - sizeof (MonoCOFFHeader) - 4);
-       if (assemblyb->pekind == 1) {
-               /* it's a dll */
-               header->coff.coff_attributes = GUINT16_FROM_LE (0x210e);
-       } else {
-               /* it's an exe */
-               header->coff.coff_attributes = GUINT16_FROM_LE (0x010e);
-       }
-
-       virtual_base = 0x400000; /* FIXME: 0x10000000 if a DLL */
-
-       header->pe.pe_magic = GUINT16_FROM_LE (0x10B);
-       header->pe.pe_major = 6;
-       header->pe.pe_minor = 0;
-       size = assembly->sections [MONO_SECTION_TEXT].size;
-       size += FILE_ALIGN - 1;
-       size &= ~(FILE_ALIGN - 1);
-       header->pe.pe_code_size = GUINT32_FROM_LE(size);
-       size = assembly->sections [MONO_SECTION_RSRC].size;
-       size += FILE_ALIGN - 1;
-       size &= ~(FILE_ALIGN - 1);
-       header->pe.pe_data_size = GUINT32_FROM_LE(size);
-       g_assert (START_TEXT_RVA == assembly->sections [MONO_SECTION_TEXT].rva);
-       header->pe.pe_rva_code_base = GUINT32_FROM_LE (assembly->sections [MONO_SECTION_TEXT].rva);
-       header->pe.pe_rva_data_base = GUINT32_FROM_LE (assembly->sections [MONO_SECTION_RSRC].rva);
-       /* pe_rva_entry_point always at the beginning of the text section */
-       header->pe.pe_rva_entry_point = GUINT32_FROM_LE (assembly->sections [MONO_SECTION_TEXT].rva);
-
-       header->nt.pe_image_base = GUINT32_FROM_LE (virtual_base);
-       header->nt.pe_section_align = GUINT32_FROM_LE (VIRT_ALIGN);
-       header->nt.pe_file_alignment = GUINT32_FROM_LE (FILE_ALIGN);
-       header->nt.pe_os_major = GUINT16_FROM_LE (4);
-       header->nt.pe_os_minor = GUINT16_FROM_LE (0);
-       header->nt.pe_subsys_major = GUINT16_FROM_LE (4);
-       size = section_start;
-       size += FILE_ALIGN - 1;
-       size &= ~(FILE_ALIGN - 1);
-       header->nt.pe_header_size = GUINT32_FROM_LE (size);
-       size = image_size;
-       size += VIRT_ALIGN - 1;
-       size &= ~(VIRT_ALIGN - 1);
-       header->nt.pe_image_size = GUINT32_FROM_LE (size);
-
-       /*
-       // Translate the PEFileKind value to the value expected by the Windows loader
-       */
-       {
-               short kind;
-
-               /*
-               // PEFileKinds.Dll == 1
-               // PEFileKinds.ConsoleApplication == 2
-               // PEFileKinds.WindowApplication == 3
-               //
-               // need to get:
-               //     IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem.
-                //     IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem.
-               */
-               if (assemblyb->pekind == 3)
-                       kind = 2;
-               else
-                       kind = 3;
-               
-               header->nt.pe_subsys_required = GUINT16_FROM_LE (kind);
-       }    
-       header->nt.pe_stack_reserve = GUINT32_FROM_LE (0x00100000);
-       header->nt.pe_stack_commit = GUINT32_FROM_LE (0x00001000);
-       header->nt.pe_heap_reserve = GUINT32_FROM_LE (0x00100000);
-       header->nt.pe_heap_commit = GUINT32_FROM_LE (0x00001000);
-       header->nt.pe_loader_flags = GUINT32_FROM_LE (0);
-       header->nt.pe_data_dir_count = GUINT32_FROM_LE (16);
-
-       /* fill data directory entries */
-
-       header->datadir.pe_resource_table.size = GUINT32_FROM_LE (assembly->sections [MONO_SECTION_RSRC].size);
-       header->datadir.pe_resource_table.rva = GUINT32_FROM_LE (assembly->sections [MONO_SECTION_RSRC].rva);
-
-       header->datadir.pe_reloc_table.size = GUINT32_FROM_LE (assembly->sections [MONO_SECTION_RELOC].size);
-       header->datadir.pe_reloc_table.rva = GUINT32_FROM_LE (assembly->sections [MONO_SECTION_RELOC].rva);
-
-       header->datadir.pe_cli_header.size = GUINT32_FROM_LE (72);
-       header->datadir.pe_cli_header.rva = GUINT32_FROM_LE (assembly->text_rva + assembly->cli_header_offset);
-       header->datadir.pe_iat.size = GUINT32_FROM_LE (8);
-       header->datadir.pe_iat.rva = GUINT32_FROM_LE (assembly->text_rva + assembly->iat_offset);
-       /* patch entrypoint name */
-       if (assemblyb->pekind == 1)
-               memcpy (assembly->code.data + assembly->imp_names_offset + 2, "_CorDllMain", 12);
-       else
-               memcpy (assembly->code.data + assembly->imp_names_offset + 2, "_CorExeMain", 12);
-       /* patch imported function RVA name */
-       rva = (guint32*)(assembly->code.data + assembly->iat_offset);
-       *rva = GUINT32_FROM_LE (assembly->text_rva + assembly->imp_names_offset);
-
-       /* the import table */
-       header->datadir.pe_import_table.size = GUINT32_FROM_LE (79); /* FIXME: magic number? */
-       header->datadir.pe_import_table.rva = GUINT32_FROM_LE (assembly->text_rva + assembly->idt_offset);
-       /* patch imported dll RVA name and other entries in the dir */
-       rva = (guint32*)(assembly->code.data + assembly->idt_offset + G_STRUCT_OFFSET (MonoIDT, name_rva));
-       *rva = GUINT32_FROM_LE (assembly->text_rva + assembly->imp_names_offset + 14); /* 14 is hint+strlen+1 of func name */
-       rva = (guint32*)(assembly->code.data + assembly->idt_offset + G_STRUCT_OFFSET (MonoIDT, import_address_table_rva));
-       *rva = GUINT32_FROM_LE (assembly->text_rva + assembly->iat_offset);
-       rva = (guint32*)(assembly->code.data + assembly->idt_offset + G_STRUCT_OFFSET (MonoIDT, import_lookup_table));
-       *rva = GUINT32_FROM_LE (assembly->text_rva + assembly->ilt_offset);
-
-       p = (guchar*)(assembly->code.data + assembly->ilt_offset);
-       value = (assembly->text_rva + assembly->imp_names_offset);
-       *p++ = (value) & 0xff;
-       *p++ = (value >> 8) & (0xff);
-       *p++ = (value >> 16) & (0xff);
-       *p++ = (value >> 24) & (0xff);
-
-       /* the CLI header info */
-       cli_header = (MonoCLIHeader*)(assembly->code.data + assembly->cli_header_offset);
-       cli_header->ch_size = GUINT32_FROM_LE (72);
-       cli_header->ch_runtime_major = GUINT16_FROM_LE (2);
-       cli_header->ch_runtime_minor = GUINT16_FROM_LE (5);
-       cli_header->ch_flags = GUINT32_FROM_LE (assemblyb->pe_kind);
-       if (assemblyb->entry_point) {
-               guint32 table_idx = 0;
-               if (!strcmp (assemblyb->entry_point->object.vtable->klass->name, "MethodBuilder")) {
-                       MonoReflectionMethodBuilder *methodb = (MonoReflectionMethodBuilder*)assemblyb->entry_point;
-                       table_idx = methodb->table_idx;
-               } else {
-                       table_idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->method_to_table_idx, assemblyb->entry_point->method));
-               }
-               cli_header->ch_entry_point = GUINT32_FROM_LE (table_idx | MONO_TOKEN_METHOD_DEF);
-       } else {
-               cli_header->ch_entry_point = GUINT32_FROM_LE (0);
-       }
-       /* The embedded managed resources */
-       text_offset = assembly->text_rva + assembly->code.index;
-       cli_header->ch_resources.rva = GUINT32_FROM_LE (text_offset);
-       cli_header->ch_resources.size = GUINT32_FROM_LE (assembly->resources.index);
-       text_offset += assembly->resources.index;
-       cli_header->ch_metadata.rva = GUINT32_FROM_LE (text_offset);
-       cli_header->ch_metadata.size = GUINT32_FROM_LE (assembly->meta_size);
-       text_offset += assembly->meta_size;
-       if (assembly->strong_name_size) {
-               cli_header->ch_strong_name.rva = GUINT32_FROM_LE (text_offset);
-               cli_header->ch_strong_name.size = GUINT32_FROM_LE (assembly->strong_name_size);
-               text_offset += assembly->strong_name_size;
-       }
-
-       /* write the section tables and section content */
-       section = (MonoSectionTable*)(pefile->data + section_start);
-       for (i = 0; i < MONO_SECTION_MAX; ++i) {
-               static const char section_names [][7] = {
-                       ".text", ".rsrc", ".reloc"
-               };
-               if (!assembly->sections [i].size)
-                       continue;
-               strcpy (section->st_name, section_names [i]);
-               /*g_print ("output section %s (%d), size: %d\n", section->st_name, i, assembly->sections [i].size);*/
-               section->st_virtual_address = GUINT32_FROM_LE (assembly->sections [i].rva);
-               section->st_virtual_size = GUINT32_FROM_LE (assembly->sections [i].size);
-               section->st_raw_data_size = GUINT32_FROM_LE (GUINT32_TO_LE (section->st_virtual_size) + (FILE_ALIGN - 1));
-               section->st_raw_data_size &= GUINT32_FROM_LE (~(FILE_ALIGN - 1));
-               section->st_raw_data_ptr = GUINT32_FROM_LE (assembly->sections [i].offset);
-               section->st_flags = GUINT32_FROM_LE (assembly->sections [i].attrs);
-               section ++;
-       }
-       
-       checked_write_file (file, pefile->data, pefile->index);
-       
-       mono_dynamic_stream_reset (pefile);
-       
-       for (i = 0; i < MONO_SECTION_MAX; ++i) {
-               if (!assembly->sections [i].size)
-                       continue;
-               
-               if (SetFilePointer (file, assembly->sections [i].offset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
-                       g_error ("SetFilePointer returned %d\n", GetLastError ());
-               
-               switch (i) {
-               case MONO_SECTION_TEXT:
-                       /* patch entry point */
-                       p = (guchar*)(assembly->code.data + 2);
-                       value = (virtual_base + assembly->text_rva + assembly->iat_offset);
-                       *p++ = (value) & 0xff;
-                       *p++ = (value >> 8) & 0xff;
-                       *p++ = (value >> 16) & 0xff;
-                       *p++ = (value >> 24) & 0xff;
-               
-                       checked_write_file (file, assembly->code.data, assembly->code.index);
-                       checked_write_file (file, assembly->resources.data, assembly->resources.index);
-                       checked_write_file (file, assembly->image.raw_metadata, assembly->meta_size);
-                       checked_write_file (file, assembly->strong_name, assembly->strong_name_size);
-                               
-
-                       g_free (assembly->image.raw_metadata);
-                       break;
-               case MONO_SECTION_RELOC: {
-                       struct {
-                               guint32 page_rva;
-                               guint32 block_size;
-                               guint16 type_and_offset;
-                               guint16 term;
-                       } reloc;
-                       
-                       g_assert (sizeof (reloc) == 12);
-                       
-                       reloc.page_rva = GUINT32_FROM_LE (assembly->text_rva);
-                       reloc.block_size = GUINT32_FROM_LE (12);
-                       
-                       /* 
-                        * the entrypoint is always at the start of the text section 
-                        * 3 is IMAGE_REL_BASED_HIGHLOW
-                        * 2 is patch_size_rva - text_rva
-                        */
-                       reloc.type_and_offset = GUINT16_FROM_LE ((3 << 12) + (2));
-                       reloc.term = 0;
-                       
-                       checked_write_file (file, &reloc, sizeof (reloc));
-                       
-                       break;
-               }
-               case MONO_SECTION_RSRC:
-                       if (assembly->win32_res) {
-
-                               /* Fixup the offsets in the IMAGE_RESOURCE_DATA_ENTRY structures */
-                               fixup_resource_directory (assembly->win32_res, assembly->win32_res, assembly->sections [i].rva);
-                               checked_write_file (file, assembly->win32_res, assembly->win32_res_size);
-                       }
-                       break;
-               default:
-                       g_assert_not_reached ();
-               }
-       }
-       
-       /* check that the file is properly padded */
-       if (SetFilePointer (file, file_offset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
-               g_error ("SetFilePointer returned %d\n", GetLastError ());
-       if (! SetEndOfFile (file))
-               g_error ("SetEndOfFile returned %d\n", GetLastError ());
-       
-       mono_dynamic_stream_reset (&assembly->code);
-       mono_dynamic_stream_reset (&assembly->us);
-       mono_dynamic_stream_reset (&assembly->blob);
-       mono_dynamic_stream_reset (&assembly->guid);
-       mono_dynamic_stream_reset (&assembly->sheap);
-
-       g_hash_table_foreach (assembly->blob_cache, (GHFunc)g_free, NULL);
-       g_hash_table_destroy (assembly->blob_cache);
-       assembly->blob_cache = NULL;
-
-       return TRUE;
-}
-
-#else /* DISABLE_REFLECTION_EMIT_SAVE */
-
-gboolean
-mono_image_create_pefile (MonoReflectionModuleBuilder *mb, HANDLE file, MonoError *error)
-{
-       g_assert_not_reached ();
-}
-
-#endif /* DISABLE_REFLECTION_EMIT_SAVE */
-
-#ifndef DISABLE_REFLECTION_EMIT
-
-MonoReflectionModule *
-mono_image_load_module_dynamic (MonoReflectionAssemblyBuilder *ab, MonoString *fileName, MonoError *error)
-{
-       char *name;
-       MonoImage *image;
-       MonoImageOpenStatus status;
-       MonoDynamicAssembly *assembly;
-       guint32 module_count;
-       MonoImage **new_modules;
-       gboolean *new_modules_loaded;
-       
-       mono_error_init (error);
-       
-       name = mono_string_to_utf8_checked (fileName, error);
-       return_val_if_nok (error, NULL);
-
-       image = mono_image_open (name, &status);
-       if (!image) {
-               if (status == MONO_IMAGE_ERROR_ERRNO)
-                       mono_error_set_exception_instance (error, mono_get_exception_file_not_found (fileName));
-               else
-                       mono_error_set_bad_image_name (error, name, NULL);
-               g_free (name);
-               return NULL;
-       }
-
-       g_free (name);
-
-       assembly = ab->dynamic_assembly;
-       image->assembly = (MonoAssembly*)assembly;
-
-       module_count = image->assembly->image->module_count;
-       new_modules = g_new0 (MonoImage *, module_count + 1);
-       new_modules_loaded = g_new0 (gboolean, module_count + 1);
-
-       if (image->assembly->image->modules)
-               memcpy (new_modules, image->assembly->image->modules, module_count * sizeof (MonoImage *));
-       if (image->assembly->image->modules_loaded)
-               memcpy (new_modules_loaded, image->assembly->image->modules_loaded, module_count * sizeof (gboolean));
-       new_modules [module_count] = image;
-       new_modules_loaded [module_count] = TRUE;
-       mono_image_addref (image);
-
-       g_free (image->assembly->image->modules);
-       image->assembly->image->modules = new_modules;
-       image->assembly->image->modules_loaded = new_modules_loaded;
-       image->assembly->image->module_count ++;
-
-       mono_assembly_load_references (image, &status);
-       if (status) {
-               mono_image_close (image);
-               mono_error_set_exception_instance (error, mono_get_exception_file_not_found (fileName));
-               return NULL;
-       }
-
-       return mono_module_get_object_checked (mono_domain_get (), image, error);
-}
-
-#endif /* DISABLE_REFLECTION_EMIT */
-
-/*
- * We need to return always the same object for MethodInfo, FieldInfo etc..
- * but we need to consider the reflected type.
- * type uses a different hash, since it uses custom hash/equal functions.
- */
-
-typedef struct {
-       gpointer item;
-       MonoClass *refclass;
-} ReflectedEntry;
-
-static gboolean
-reflected_equal (gconstpointer a, gconstpointer b) {
-       const ReflectedEntry *ea = (const ReflectedEntry *)a;
-       const ReflectedEntry *eb = (const ReflectedEntry *)b;
-
-       return (ea->item == eb->item) && (ea->refclass == eb->refclass);
-}
-
-static guint
-reflected_hash (gconstpointer a) {
-       const ReflectedEntry *ea = (const ReflectedEntry *)a;
-       return mono_aligned_addr_hash (ea->item);
-}
-
-#define CHECK_OBJECT(t,p,k)    \
-       do {    \
-               t _obj; \
-               ReflectedEntry e;       \
-               e.item = (p);   \
-               e.refclass = (k);       \
-               mono_domain_lock (domain);      \
-               if (!domain->refobject_hash)    \
-                       domain->refobject_hash = mono_g_hash_table_new_type (reflected_hash, reflected_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection objects table");  \
-               if ((_obj = (t)mono_g_hash_table_lookup (domain->refobject_hash, &e))) {        \
-                       mono_domain_unlock (domain);    \
-                       return _obj;    \
-               }       \
-        mono_domain_unlock (domain); \
-       } while (0)
-
-#ifdef HAVE_BOEHM_GC
-/* ReflectedEntry doesn't need to be GC tracked */
-#define ALLOC_REFENTRY g_new0 (ReflectedEntry, 1)
-#define FREE_REFENTRY(entry) g_free ((entry))
-#define REFENTRY_REQUIRES_CLEANUP
-#else
-#define ALLOC_REFENTRY (ReflectedEntry *)mono_mempool_alloc (domain->mp, sizeof (ReflectedEntry))
-/* FIXME: */
-#define FREE_REFENTRY(entry)
-#endif
-
-#define CACHE_OBJECT(t,p,o,k)  \
-       do {    \
-               t _obj; \
-        ReflectedEntry pe; \
-        pe.item = (p); \
-        pe.refclass = (k); \
-        mono_domain_lock (domain); \
-               if (!domain->refobject_hash)    \
-                       domain->refobject_hash = mono_g_hash_table_new_type (reflected_hash, reflected_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection objects table");  \
-        _obj = (t)mono_g_hash_table_lookup (domain->refobject_hash, &pe); \
-        if (!_obj) { \
-                   ReflectedEntry *e = ALLOC_REFENTRY;         \
-                   e->item = (p);      \
-                   e->refclass = (k);  \
-                   mono_g_hash_table_insert (domain->refobject_hash, e,o);     \
-            _obj = o; \
-        } \
-               mono_domain_unlock (domain);    \
-        return _obj; \
-       } while (0)
-
-static void
-clear_cached_object (MonoDomain *domain, gpointer o, MonoClass *klass)
-{
-       mono_domain_lock (domain);
-       if (domain->refobject_hash) {
-        ReflectedEntry pe;
-               gpointer orig_pe, orig_value;
-
-               pe.item = o;
-               pe.refclass = klass;
-               if (mono_g_hash_table_lookup_extended (domain->refobject_hash, &pe, &orig_pe, &orig_value)) {
-                       mono_g_hash_table_remove (domain->refobject_hash, &pe);
-                       FREE_REFENTRY (orig_pe);
-               }
-       }
-       mono_domain_unlock (domain);
-}
-
-#ifdef REFENTRY_REQUIRES_CLEANUP
-static void
-cleanup_refobject_hash (gpointer key, gpointer value, gpointer user_data)
-{
-       FREE_REFENTRY (key);
-}
-#endif
-
-void
-mono_reflection_cleanup_domain (MonoDomain *domain)
-{
-       if (domain->refobject_hash) {
-/*let's avoid scanning the whole hashtable if not needed*/
-#ifdef REFENTRY_REQUIRES_CLEANUP
-               mono_g_hash_table_foreach (domain->refobject_hash, cleanup_refobject_hash, NULL);
-#endif
-               mono_g_hash_table_destroy (domain->refobject_hash);
-               domain->refobject_hash = NULL;
-       }
-}
-
-#ifndef DISABLE_REFLECTION_EMIT
-static gpointer
-register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly)
-{
-       CACHE_OBJECT (MonoReflectionAssembly *, assembly, res, NULL);
-}
-
-static gpointer
-register_module (MonoDomain *domain, MonoReflectionModuleBuilder *res, MonoDynamicImage *module)
-{
-       CACHE_OBJECT (MonoReflectionModuleBuilder *, module, res, NULL);
-}
-
-static gboolean
-image_module_basic_init (MonoReflectionModuleBuilder *moduleb, MonoError *error)
-{
-       MonoDynamicImage *image = moduleb->dynamic_image;
-       MonoReflectionAssemblyBuilder *ab = moduleb->assemblyb;
-       mono_error_init (error);
-       if (!image) {
-               int module_count;
-               MonoImage **new_modules;
-               MonoImage *ass;
-               char *name, *fqname;
-               /*
-                * FIXME: we already created an image in mono_image_basic_init (), but
-                * we don't know which module it belongs to, since that is only 
-                * determined at assembly save time.
-                */
-               /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
-               name = mono_string_to_utf8_checked (ab->name, error);
-               return_val_if_nok (error, FALSE);
-               fqname = mono_string_to_utf8_checked (moduleb->module.fqname, error);
-               if (!is_ok (error)) {
-                       g_free (name);
-                       return FALSE;
-               }
-               image = create_dynamic_mono_image (ab->dynamic_assembly, name, fqname);
-
-               moduleb->module.image = &image->image;
-               moduleb->dynamic_image = image;
-               register_module (mono_object_domain (moduleb), moduleb, image);
-
-               /* register the module with the assembly */
-               ass = ab->dynamic_assembly->assembly.image;
-               module_count = ass->module_count;
-               new_modules = g_new0 (MonoImage *, module_count + 1);
-
-               if (ass->modules)
-                       memcpy (new_modules, ass->modules, module_count * sizeof (MonoImage *));
-               new_modules [module_count] = &image->image;
-               mono_image_addref (&image->image);
-
-               g_free (ass->modules);
-               ass->modules = new_modules;
-               ass->module_count ++;
-       }
-       return TRUE;
-}
-
-static void
-mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
-{
-       MonoError error;
-       (void) image_module_basic_init (moduleb, &error);
-       mono_error_set_pending_exception (&error);
-}
-
-#endif
-
-/*
- * mono_assembly_get_object:
- * @domain: an app domain
- * @assembly: an assembly
- *
- * Return an System.Reflection.Assembly object representing the MonoAssembly @assembly.
- */
-MonoReflectionAssembly*
-mono_assembly_get_object (MonoDomain *domain, MonoAssembly *assembly)
-{
-       MonoError error;
-       MonoReflectionAssembly *result;
-       result = mono_assembly_get_object_checked (domain, assembly, &error);
-       mono_error_cleanup (&error); /* FIXME new API that doesn't swallow the error */
-       return result;
-}
-/*
- * mono_assembly_get_object_checked:
- * @domain: an app domain
- * @assembly: an assembly
- *
- * Return an System.Reflection.Assembly object representing the MonoAssembly @assembly.
- */
-MonoReflectionAssembly*
-mono_assembly_get_object_checked (MonoDomain *domain, MonoAssembly *assembly, MonoError *error)
-{
-       MonoReflectionAssembly *res;
-       
-       mono_error_init (error);
-
-       CHECK_OBJECT (MonoReflectionAssembly *, assembly, NULL);
-       res = (MonoReflectionAssembly *)mono_object_new_checked (domain, mono_class_get_mono_assembly_class (), error);
-       if (!res)
-               return NULL;
-       res->assembly = assembly;
-
-       CACHE_OBJECT (MonoReflectionAssembly *, assembly, res, NULL);
-}
-
-
-
-MonoReflectionModule*   
-mono_module_get_object   (MonoDomain *domain, MonoImage *image)
-{
-       MonoError error;
-       MonoReflectionModule *result;
-       result = mono_module_get_object_checked (domain, image, &error);
-       mono_error_cleanup (&error);
-       return result;
-}
-
-MonoReflectionModule*
-mono_module_get_object_checked (MonoDomain *domain, MonoImage *image, MonoError *error)
-{
-       MonoReflectionModule *res;
-       char* basename;
-       
-       mono_error_init (error);
-       CHECK_OBJECT (MonoReflectionModule *, image, NULL);
-       res = (MonoReflectionModule *)mono_object_new_checked (domain, mono_class_get_mono_module_class (), error);
-       if (!res)
-               return NULL;
-
-       res->image = image;
-       MonoReflectionAssembly *assm_obj = mono_assembly_get_object_checked (domain, image->assembly, error);
-       if (!assm_obj)
-               return NULL;
-       MONO_OBJECT_SETREF (res, assembly, assm_obj);
-
-       MONO_OBJECT_SETREF (res, fqname, mono_string_new (domain, image->name));
-       basename = g_path_get_basename (image->name);
-       MONO_OBJECT_SETREF (res, name, mono_string_new (domain, basename));
-       MONO_OBJECT_SETREF (res, scopename, mono_string_new (domain, image->module_name));
-       
-       g_free (basename);
-
-       if (image->assembly->image == image) {
-               res->token = mono_metadata_make_token (MONO_TABLE_MODULE, 1);
-       } else {
-               int i;
-               res->token = 0;
-               if (image->assembly->image->modules) {
-                       for (i = 0; i < image->assembly->image->module_count; i++) {
-                               if (image->assembly->image->modules [i] == image)
-                                       res->token = mono_metadata_make_token (MONO_TABLE_MODULEREF, i + 1);
-                       }
-                       g_assert (res->token);
-               }
-       }
-
-       CACHE_OBJECT (MonoReflectionModule *, image, res, NULL);
-}
-
-MonoReflectionModule*
-mono_module_file_get_object (MonoDomain *domain, MonoImage *image, int table_index)
-{
-       MonoError error;
-       MonoReflectionModule *result;
-       result = mono_module_file_get_object_checked (domain, image, table_index, &error);
-       mono_error_cleanup (&error);
-       return result;
-}
-
-MonoReflectionModule*
-mono_module_file_get_object_checked (MonoDomain *domain, MonoImage *image, int table_index, MonoError *error)
-{
-       MonoReflectionModule *res;
-       MonoTableInfo *table;
-       guint32 cols [MONO_FILE_SIZE];
-       const char *name;
-       guint32 i, name_idx;
-       const char *val;
-       
-       mono_error_init (error);
-
-       res = (MonoReflectionModule *)mono_object_new_checked (domain, mono_class_get_mono_module_class (), error);
-       if (!res)
-               return NULL;
-
-       table = &image->tables [MONO_TABLE_FILE];
-       g_assert (table_index < table->rows);
-       mono_metadata_decode_row (table, table_index, cols, MONO_FILE_SIZE);
-
-       res->image = NULL;
-       MonoReflectionAssembly *assm_obj = mono_assembly_get_object_checked (domain, image->assembly, error);
-       if (!assm_obj)
-               return NULL;
-       MONO_OBJECT_SETREF (res, assembly, assm_obj);
-       name = mono_metadata_string_heap (image, cols [MONO_FILE_NAME]);
-
-       /* Check whenever the row has a corresponding row in the moduleref table */
-       table = &image->tables [MONO_TABLE_MODULEREF];
-       for (i = 0; i < table->rows; ++i) {
-               name_idx = mono_metadata_decode_row_col (table, i, MONO_MODULEREF_NAME);
-               val = mono_metadata_string_heap (image, name_idx);
-               if (strcmp (val, name) == 0)
-                       res->image = image->modules [i];
-       }
-
-       MONO_OBJECT_SETREF (res, fqname, mono_string_new (domain, name));
-       MONO_OBJECT_SETREF (res, name, mono_string_new (domain, name));
-       MONO_OBJECT_SETREF (res, scopename, mono_string_new (domain, name));
-       res->is_resource = cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA;
-       res->token = mono_metadata_make_token (MONO_TABLE_FILE, table_index + 1);
-
-       return res;
-}
-
-static gboolean
-verify_safe_for_managed_space (MonoType *type)
-{
-       switch (type->type) {
-#ifdef DEBUG_HARDER
-       case MONO_TYPE_ARRAY:
-               return verify_safe_for_managed_space (&type->data.array->eklass->byval_arg);
-       case MONO_TYPE_PTR:
-               return verify_safe_for_managed_space (type->data.type);
-       case MONO_TYPE_SZARRAY:
-               return verify_safe_for_managed_space (&type->data.klass->byval_arg);
-       case MONO_TYPE_GENERICINST: {
-               MonoGenericInst *inst = type->data.generic_class->inst;
-               int i;
-               if (!inst->is_open)
-                       break;
-               for (i = 0; i < inst->type_argc; ++i)
-                       if (!verify_safe_for_managed_space (inst->type_argv [i]))
-                               return FALSE;
-               return TRUE;
-       }
-#endif
-       case MONO_TYPE_VAR:
-       case MONO_TYPE_MVAR:
-               return TRUE;
-       default:
-               return TRUE;
-       }
-}
-
-static MonoType*
-mono_type_normalize (MonoType *type)
-{
-       int i;
-       MonoGenericClass *gclass;
-       MonoGenericInst *ginst;
-       MonoClass *gtd;
-       MonoGenericContainer *gcontainer;
-       MonoType **argv = NULL;
-       gboolean is_denorm_gtd = TRUE, requires_rebind = FALSE;
-
-       if (type->type != MONO_TYPE_GENERICINST)
-               return type;
-
-       gclass = type->data.generic_class;
-       ginst = gclass->context.class_inst;
-       if (!ginst->is_open)
-               return type;
-
-       gtd = gclass->container_class;
-       gcontainer = gtd->generic_container;
-       argv = g_newa (MonoType*, ginst->type_argc);
-
-       for (i = 0; i < ginst->type_argc; ++i) {
-               MonoType *t = ginst->type_argv [i], *norm;
-               if (t->type != MONO_TYPE_VAR || t->data.generic_param->num != i || t->data.generic_param->owner != gcontainer)
-                       is_denorm_gtd = FALSE;
-               norm = mono_type_normalize (t);
-               argv [i] = norm;
-               if (norm != t)
-                       requires_rebind = TRUE;
-       }
-
-       if (is_denorm_gtd)
-               return type->byref == gtd->byval_arg.byref ? &gtd->byval_arg : &gtd->this_arg;
-
-       if (requires_rebind) {
-               MonoClass *klass = mono_class_bind_generic_parameters (gtd, ginst->type_argc, argv, gclass->is_dynamic);
-               return type->byref == klass->byval_arg.byref ? &klass->byval_arg : &klass->this_arg;
-       }
-
-       return type;
-}
-/*
- * mono_type_get_object:
- * @domain: an app domain
- * @type: a type
- *
- * Return an System.MonoType object representing the type @type.
- */
-MonoReflectionType*
-mono_type_get_object (MonoDomain *domain, MonoType *type)
-{
-       MonoError error;
-       MonoReflectionType *ret = mono_type_get_object_checked (domain, type, &error);
-       mono_error_cleanup (&error);
-
-       return ret;
-}
-
-MonoReflectionType*
-mono_type_get_object_checked (MonoDomain *domain, MonoType *type, MonoError *error)
-{
-       MonoType *norm_type;
-       MonoReflectionType *res;
-       MonoClass *klass;
-
-       mono_error_init (error);
-
-       klass = mono_class_from_mono_type (type);
-
-       /*we must avoid using @type as it might have come
-        * from a mono_metadata_type_dup and the caller
-        * expects that is can be freed.
-        * Using the right type from 
-        */
-       type = klass->byval_arg.byref == type->byref ? &klass->byval_arg : &klass->this_arg;
-
-       /* void is very common */
-       if (type->type == MONO_TYPE_VOID && domain->typeof_void)
-               return (MonoReflectionType*)domain->typeof_void;
-
-       /*
-        * If the vtable of the given class was already created, we can use
-        * the MonoType from there and avoid all locking and hash table lookups.
-        * 
-        * We cannot do this for TypeBuilders as mono_reflection_create_runtime_class expects
-        * that the resulting object is different.   
-        */
-       if (type == &klass->byval_arg && !image_is_dynamic (klass->image)) {
-               MonoVTable *vtable = mono_class_try_get_vtable (domain, klass);
-               if (vtable && vtable->type)
-                       return (MonoReflectionType *)vtable->type;
-       }
-
-       mono_loader_lock (); /*FIXME mono_class_init and mono_class_vtable acquire it*/
-       mono_domain_lock (domain);
-       if (!domain->type_hash)
-               domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mono_metadata_type_hash, 
-                               (GCompareFunc)mono_metadata_type_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection types table");
-       if ((res = (MonoReflectionType *)mono_g_hash_table_lookup (domain->type_hash, type))) {
-               mono_domain_unlock (domain);
-               mono_loader_unlock ();
-               return res;
-       }
-
-       /*Types must be normalized so a generic instance of the GTD get's the same inner type.
-        * For example in: Foo<A,B>; Bar<A> : Foo<A, Bar<A>>
-        * The second Bar will be encoded a generic instance of Bar with <A> as parameter.
-        * On all other places, Bar<A> will be encoded as the GTD itself. This is an implementation
-        * artifact of how generics are encoded and should be transparent to managed code so we
-        * need to weed out this diference when retrieving managed System.Type objects.
-        */
-       norm_type = mono_type_normalize (type);
-       if (norm_type != type) {
-               res = mono_type_get_object_checked (domain, norm_type, error);
-               if (!mono_error_ok (error))
-                       return NULL;
-               mono_g_hash_table_insert (domain->type_hash, type, res);
-               mono_domain_unlock (domain);
-               mono_loader_unlock ();
-               return res;
-       }
-
-       /* This MonoGenericClass hack is no longer necessary. Let's leave it here until we finish with the 2-stage type-builder setup.*/
-       if ((type->type == MONO_TYPE_GENERICINST) && type->data.generic_class->is_dynamic && !type->data.generic_class->container_class->wastypebuilder)
-               g_assert (0);
-
-       if (!verify_safe_for_managed_space (type)) {
-               mono_domain_unlock (domain);
-               mono_loader_unlock ();
-               mono_error_set_generic_error (error, "System", "InvalidOperationException", "This type cannot be propagated to managed space");
-               return NULL;
-       }
-
-       if (mono_class_get_ref_info (klass) && !klass->wastypebuilder) {
-               gboolean is_type_done = TRUE;
-               /* Generic parameters have reflection_info set but they are not finished together with their enclosing type.
-                * We must ensure that once a type is finished we don't return a GenericTypeParameterBuilder.
-                * We can't simply close the types as this will interfere with other parts of the generics machinery.
-               */
-               if (klass->byval_arg.type == MONO_TYPE_MVAR || klass->byval_arg.type == MONO_TYPE_VAR) {
-                       MonoGenericParam *gparam = klass->byval_arg.data.generic_param;
-
-                       if (gparam->owner && gparam->owner->is_method) {
-                               MonoMethod *method = gparam->owner->owner.method;
-                               if (method && mono_class_get_generic_type_definition (method->klass)->wastypebuilder)
-                                       is_type_done = FALSE;
-                       } else if (gparam->owner && !gparam->owner->is_method) {
-                               MonoClass *klass = gparam->owner->owner.klass;
-                               if (klass && mono_class_get_generic_type_definition (klass)->wastypebuilder)
-                                       is_type_done = FALSE;
-                       }
-               } 
-
-               /* g_assert_not_reached (); */
-               /* should this be considered an error condition? */
-               if (is_type_done && !type->byref) {
-                       mono_domain_unlock (domain);
-                       mono_loader_unlock ();
-                       return (MonoReflectionType *)mono_class_get_ref_info (klass);
-               }
-       }
-       /* This is stored in vtables/JITted code so it has to be pinned */
-       res = (MonoReflectionType *)mono_object_new_pinned (domain, mono_defaults.runtimetype_class, error);
-       if (!mono_error_ok (error))
-               return NULL;
-
-       res->type = type;
-       mono_g_hash_table_insert (domain->type_hash, type, res);
-
-       if (type->type == MONO_TYPE_VOID)
-               domain->typeof_void = (MonoObject*)res;
-
-       mono_domain_unlock (domain);
-       mono_loader_unlock ();
-       return res;
-}
-
-/*
- * mono_method_get_object:
- * @domain: an app domain
- * @method: a method
- * @refclass: the reflected type (can be NULL)
- *
- * Return an System.Reflection.MonoMethod object representing the method @method.
- */
-MonoReflectionMethod*
-mono_method_get_object (MonoDomain *domain, MonoMethod *method, MonoClass *refclass)
-{
-       MonoError error;
-       MonoReflectionMethod *ret = NULL;
-       ret = mono_method_get_object_checked (domain, method, refclass, &error);
-       mono_error_cleanup (&error);
-       return ret;
-}
-
-/*
- * mono_method_get_object_checked:
- * @domain: an app domain
- * @method: a method
- * @refclass: the reflected type (can be NULL)
- * @error: set on error.
- *
- * Return an System.Reflection.MonoMethod object representing the method @method.
- * Returns NULL and sets @error on error.
- */
-MonoReflectionMethod*
-mono_method_get_object_checked (MonoDomain *domain, MonoMethod *method, MonoClass *refclass, MonoError *error)
-{
-       /*
-        * We use the same C representation for methods and constructors, but the type 
-        * name in C# is different.
-        */
-       MonoReflectionType *rt;
-       MonoClass *klass;
-       MonoReflectionMethod *ret;
-
-       mono_error_init (error);
-
-       if (method->is_inflated) {
-               MonoReflectionGenericMethod *gret;
-
-               if (!refclass)
-                       refclass = method->klass;
-               CHECK_OBJECT (MonoReflectionMethod *, method, refclass);
-               if ((*method->name == '.') && (!strcmp (method->name, ".ctor") || !strcmp (method->name, ".cctor"))) {
-                       klass = mono_class_get_mono_generic_cmethod_class ();
-               } else {
-                       klass = mono_class_get_mono_generic_method_class ();
-               }
-               gret = (MonoReflectionGenericMethod*)mono_object_new_checked (domain, klass, error);
-               if (!mono_error_ok (error))
-                       goto leave;
-               gret->method.method = method;
-
-               MONO_OBJECT_SETREF (gret, method.name, mono_string_new (domain, method->name));
-
-               rt = mono_type_get_object_checked (domain, &refclass->byval_arg, error);
-               if (!mono_error_ok (error))
-                   goto leave;
-
-               MONO_OBJECT_SETREF (gret, method.reftype, rt);
-
-               CACHE_OBJECT (MonoReflectionMethod *, method, (MonoReflectionMethod*)gret, refclass);
-       }
-
-       if (!refclass)
-               refclass = method->klass;
-
-       CHECK_OBJECT (MonoReflectionMethod *, method, refclass);
-       if (*method->name == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0)) {
-               klass = mono_class_get_mono_cmethod_class ();
-       }
-       else {
-               klass = mono_class_get_mono_method_class ();
-       }
-       ret = (MonoReflectionMethod*)mono_object_new_checked (domain, klass, error);
-       if (!mono_error_ok (error))
-               goto leave;
-       ret->method = method;
-
-       rt = mono_type_get_object_checked (domain, &refclass->byval_arg, error);
-       if (!mono_error_ok (error))
-               goto leave;
-
-       MONO_OBJECT_SETREF (ret, reftype, rt);
-
-       CACHE_OBJECT (MonoReflectionMethod *, method, ret, refclass);
-
-leave:
-       g_assert (!mono_error_ok (error));
-       return NULL;
-}
-
-/*
- * mono_method_clear_object:
- *
- *   Clear the cached reflection objects for the dynamic method METHOD.
- */
-void
-mono_method_clear_object (MonoDomain *domain, MonoMethod *method)
-{
-       MonoClass *klass;
-       g_assert (method_is_dynamic (method));
-
-       klass = method->klass;
-       while (klass) {
-               clear_cached_object (domain, method, klass);
-               klass = klass->parent;
-       }
-       /* Added by mono_param_get_objects () */
-       clear_cached_object (domain, &(method->signature), NULL);
-       klass = method->klass;
-       while (klass) {
-               clear_cached_object (domain, &(method->signature), klass);
-               klass = klass->parent;
-       }
-}
-
-/*
- * mono_field_get_object:
- * @domain: an app domain
- * @klass: a type
- * @field: a field
- *
- * Return an System.Reflection.MonoField object representing the field @field
- * in class @klass.
- */
-MonoReflectionField*
-mono_field_get_object (MonoDomain *domain, MonoClass *klass, MonoClassField *field)
-{
-       MonoError error;
-       MonoReflectionField *result;
-       result = mono_field_get_object_checked (domain, klass, field, &error);
-       mono_error_cleanup (&error);
-       return result;
-}
-
-/*
- * mono_field_get_object_checked:
- * @domain: an app domain
- * @klass: a type
- * @field: a field
- * @error: set on error
- *
- * Return an System.Reflection.MonoField object representing the field @field
- * in class @klass. On error, returns NULL and sets @error.
- */
-MonoReflectionField*
-mono_field_get_object_checked (MonoDomain *domain, MonoClass *klass, MonoClassField *field, MonoError *error)
-{
-       MonoReflectionType *rt;
-       MonoReflectionField *res;
-
-       mono_error_init (error);
-
-       CHECK_OBJECT (MonoReflectionField *, field, klass);
-       res = (MonoReflectionField *)mono_object_new_checked (domain, mono_class_get_mono_field_class (), error);
-       if (!res)
-               return NULL;
-       res->klass = klass;
-       res->field = field;
-       MONO_OBJECT_SETREF (res, name, mono_string_new (domain, mono_field_get_name (field)));
-
-       if (is_field_on_inst (field)) {
-               res->attrs = get_field_on_inst_generic_type (field)->attrs;
-
-               rt = mono_type_get_object_checked (domain, field->type, error);
-               if (!mono_error_ok (error))
-                       return NULL;
-
-               MONO_OBJECT_SETREF (res, type, rt);
-       } else {
-               if (field->type) {
-                       rt = mono_type_get_object_checked (domain, field->type, error);
-                       if (!mono_error_ok (error))
-                               return NULL;
-
-                       MONO_OBJECT_SETREF (res, type, rt);
-               }
-               res->attrs = mono_field_get_flags (field);
-       }
-       CACHE_OBJECT (MonoReflectionField *, field, res, klass);
-}
-
-/*
- * mono_property_get_object:
- * @domain: an app domain
- * @klass: a type
- * @property: a property
- *
- * Return an System.Reflection.MonoProperty object representing the property @property
- * in class @klass.
- */
-MonoReflectionProperty*
-mono_property_get_object (MonoDomain *domain, MonoClass *klass, MonoProperty *property)
-{
-       MonoError error;
-       MonoReflectionProperty *result;
-       result = mono_property_get_object_checked (domain, klass, property, &error);
-       mono_error_cleanup (&error);
-       return result;
-}
-
-/**
- * mono_property_get_object:
- * @domain: an app domain
- * @klass: a type
- * @property: a property
- * @error: set on error
- *
- * Return an System.Reflection.MonoProperty object representing the property @property
- * in class @klass.  On error returns NULL and sets @error.
- */
-MonoReflectionProperty*
-mono_property_get_object_checked (MonoDomain *domain, MonoClass *klass, MonoProperty *property, MonoError *error)
-{
-       MonoReflectionProperty *res;
-
-       mono_error_init (error);
-
-       CHECK_OBJECT (MonoReflectionProperty *, property, klass);
-       res = (MonoReflectionProperty *)mono_object_new_checked (domain, mono_class_get_mono_property_class (), error);
-       if (!res)
-               return NULL;
-       res->klass = klass;
-       res->property = property;
-       CACHE_OBJECT (MonoReflectionProperty *, property, res, klass);
-}
-
-/*
- * mono_event_get_object:
- * @domain: an app domain
- * @klass: a type
- * @event: a event
- *
- * Return an System.Reflection.MonoEvent object representing the event @event
- * in class @klass.
- */
-MonoReflectionEvent*
-mono_event_get_object (MonoDomain *domain, MonoClass *klass, MonoEvent *event)
-{
-       MonoError error;
-       MonoReflectionEvent *result;
-       result = mono_event_get_object_checked (domain, klass, event, &error);
-       mono_error_cleanup (&error);
-       return result;
-}
-
-/**
- * mono_event_get_object_checked:
- * @domain: an app domain
- * @klass: a type
- * @event: a event
- * @error: set on error
- *
- * Return an System.Reflection.MonoEvent object representing the event @event
- * in class @klass. On failure sets @error and returns NULL
- */
-MonoReflectionEvent*
-mono_event_get_object_checked (MonoDomain *domain, MonoClass *klass, MonoEvent *event, MonoError *error)
-{
-       MonoReflectionEvent *res;
-       MonoReflectionMonoEvent *mono_event;
-
-       mono_error_init (error);
-       CHECK_OBJECT (MonoReflectionEvent *, event, klass);
-       mono_event = (MonoReflectionMonoEvent *)mono_object_new_checked (domain, mono_class_get_mono_event_class (), error);
-       if (!mono_event)
-               return NULL;
-       mono_event->klass = klass;
-       mono_event->event = event;
-       res = (MonoReflectionEvent*)mono_event;
-       CACHE_OBJECT (MonoReflectionEvent *, event, res, klass);
-}
-
-/**
- * mono_get_reflection_missing_object:
- * @domain: Domain where the object lives
- *
- * Returns the System.Reflection.Missing.Value singleton object
- * (of type System.Reflection.Missing).
- *
- * Used as the value for ParameterInfo.DefaultValue when Optional
- * is present
- */
-static MonoObject *
-mono_get_reflection_missing_object (MonoDomain *domain)
-{
-       MonoError error;
-       MonoObject *obj;
-       static MonoClassField *missing_value_field = NULL;
-       
-       if (!missing_value_field) {
-               MonoClass *missing_klass;
-               missing_klass = mono_class_get_missing_class ();
-               mono_class_init (missing_klass);
-               missing_value_field = mono_class_get_field_from_name (missing_klass, "Value");
-               g_assert (missing_value_field);
-       }
-       obj = mono_field_get_value_object_checked (domain, missing_value_field, NULL, &error);
-       mono_error_assert_ok (&error);
-       return obj;
-}
-
-static MonoObject*
-get_dbnull (MonoDomain *domain, MonoObject **dbnull)
-{
-       if (!*dbnull)
-               *dbnull = mono_get_dbnull_object (domain);
-       return *dbnull;
-}
-
-static MonoObject*
-get_reflection_missing (MonoDomain *domain, MonoObject **reflection_missing)
-{
-       if (!*reflection_missing)
-               *reflection_missing = mono_get_reflection_missing_object (domain);
-       return *reflection_missing;
-}
-
-/*
- * mono_param_get_objects:
- * @domain: an app domain
- * @method: a method
- *
- * Return an System.Reflection.ParameterInfo array object representing the parameters
- * in the method @method.
- */
-MonoArray*
-mono_param_get_objects_internal (MonoDomain *domain, MonoMethod *method, MonoClass *refclass, MonoError *error)
-{
-       static MonoClass *System_Reflection_ParameterInfo;
-       static MonoClass *System_Reflection_ParameterInfo_array;
-       MonoArray *res = NULL;
-       MonoReflectionMethod *member = NULL;
-       MonoReflectionParameter *param = NULL;
-       char **names = NULL, **blobs = NULL;
-       guint32 *types = NULL;
-       MonoType *type = NULL;
-       MonoObject *dbnull = NULL;
-       MonoObject *missing = NULL;
-       MonoMarshalSpec **mspecs = NULL;
-       MonoMethodSignature *sig = NULL;
-       MonoVTable *pinfo_vtable;
-       MonoReflectionType *rt;
-       int i;
-
-       mono_error_init (error);
-       
-       if (!System_Reflection_ParameterInfo_array) {
-               MonoClass *klass;
-
-               klass = mono_class_get_mono_parameter_info_class ();
-
-               mono_memory_barrier ();
-               System_Reflection_ParameterInfo = klass; 
-
-       
-               klass = mono_array_class_get (klass, 1);
-               mono_memory_barrier ();
-               System_Reflection_ParameterInfo_array = klass;
-       }
-
-       sig = mono_method_signature_checked (method, error);
-       if (!mono_error_ok (error))
-               goto leave;
-
-       if (!sig->param_count) {
-               res = mono_array_new_specific_checked (mono_class_vtable (domain, System_Reflection_ParameterInfo_array), 0, error);
-               if (!res)
-                       goto leave;
-
-               return res;
-       }
-
-       /* Note: the cache is based on the address of the signature into the method
-        * since we already cache MethodInfos with the method as keys.
-        */
-       CHECK_OBJECT (MonoArray*, &(method->signature), refclass);
-
-       member = mono_method_get_object_checked (domain, method, refclass, error);
-       if (!member)
-               goto leave;
-       names = g_new (char *, sig->param_count);
-       mono_method_get_param_names (method, (const char **) names);
-
-       mspecs = g_new (MonoMarshalSpec*, sig->param_count + 1);
-       mono_method_get_marshal_info (method, mspecs);
-
-       res = mono_array_new_specific_checked (mono_class_vtable (domain, System_Reflection_ParameterInfo_array), sig->param_count, error);
-       if (!res)
-               goto leave;
-
-       pinfo_vtable = mono_class_vtable (domain, System_Reflection_ParameterInfo);
-       for (i = 0; i < sig->param_count; ++i) {
-               param = (MonoReflectionParameter *) mono_object_new_specific_checked (pinfo_vtable, error);
-               if (!param)
-                       goto leave;
-
-               rt = mono_type_get_object_checked (domain, sig->params [i], error);
-               if (!rt)
-                       goto leave;
-
-               MONO_OBJECT_SETREF (param, ClassImpl, rt);
-
-               MONO_OBJECT_SETREF (param, MemberImpl, (MonoObject*)member);
-
-               MONO_OBJECT_SETREF (param, NameImpl, mono_string_new (domain, names [i]));
-
-               param->PositionImpl = i;
-               param->AttrsImpl = sig->params [i]->attrs;
-
-               if (!(param->AttrsImpl & PARAM_ATTRIBUTE_HAS_DEFAULT)) {
-                       if (param->AttrsImpl & PARAM_ATTRIBUTE_OPTIONAL)
-                               MONO_OBJECT_SETREF (param, DefaultValueImpl, get_reflection_missing (domain, &missing));
-                       else
-                               MONO_OBJECT_SETREF (param, DefaultValueImpl, get_dbnull (domain, &dbnull));
-               } else {
-
-                       if (!blobs) {
-                               blobs = g_new0 (char *, sig->param_count);
-                               types = g_new0 (guint32, sig->param_count);
-                               get_default_param_value_blobs (method, blobs, types); 
-                       }
-
-                       /* Build MonoType for the type from the Constant Table */
-                       if (!type)
-                               type = g_new0 (MonoType, 1);
-                       type->type = (MonoTypeEnum)types [i];
-                       type->data.klass = NULL;
-                       if (types [i] == MONO_TYPE_CLASS)
-                               type->data.klass = mono_defaults.object_class;
-                       else if ((sig->params [i]->type == MONO_TYPE_VALUETYPE) && sig->params [i]->data.klass->enumtype) {
-                               /* For enums, types [i] contains the base type */
-
-                                       type->type = MONO_TYPE_VALUETYPE;
-                                       type->data.klass = mono_class_from_mono_type (sig->params [i]);
-                       } else
-                               type->data.klass = mono_class_from_mono_type (type);
-
-                       MonoObject *default_val_obj = mono_get_object_from_blob (domain, type, blobs [i], error);
-                       if (!is_ok (error))
-                               goto leave;
-                       MONO_OBJECT_SETREF (param, DefaultValueImpl, default_val_obj);
-
-                       /* Type in the Constant table is MONO_TYPE_CLASS for nulls */
-                       if (types [i] != MONO_TYPE_CLASS && !param->DefaultValueImpl) {
-                               if (param->AttrsImpl & PARAM_ATTRIBUTE_OPTIONAL)
-                                       MONO_OBJECT_SETREF (param, DefaultValueImpl, get_reflection_missing (domain, &missing));
-                               else
-                                       MONO_OBJECT_SETREF (param, DefaultValueImpl, get_dbnull (domain, &dbnull));
-                       }
-                       
-               }
-
-               if (mspecs [i + 1]) {
-                       MonoReflectionMarshalAsAttribute* mobj;
-                       mobj = mono_reflection_marshal_as_attribute_from_marshal_spec (domain, method->klass, mspecs [i + 1], error);
-                       if (!mobj)
-                               goto leave;
-                       MONO_OBJECT_SETREF (param, MarshalAsImpl, (MonoObject*)mobj);
-               }
-               
-               mono_array_setref (res, i, param);
-       }
-
-leave:
-       g_free (names);
-       g_free (blobs);
-       g_free (types);
-       g_free (type);
-
-       if (sig) {
-               for (i = sig->param_count; i >= 0; i--) {
-                       if (mspecs [i])
-                               mono_metadata_free_marshal_spec (mspecs [i]);
-               }
-       }
-       g_free (mspecs);
-
-       if (!is_ok (error))
-               return NULL;
-       
-       CACHE_OBJECT (MonoArray *, &(method->signature), res, refclass);
-}
-
-MonoArray*
-mono_param_get_objects (MonoDomain *domain, MonoMethod *method)
-{
-       MonoError error;
-       MonoArray *result = mono_param_get_objects_internal (domain, method, NULL, &error);
-       mono_error_assert_ok (&error);
-       return result;
-}
-
-/*
- * mono_method_body_get_object:
- * @domain: an app domain
- * @method: a method
- *
- * Return an System.Reflection.MethodBody object representing the method @method.
- */
-MonoReflectionMethodBody*
-mono_method_body_get_object (MonoDomain *domain, MonoMethod *method)
-{
-       MonoError error;
-       MonoReflectionMethodBody *result = mono_method_body_get_object_checked (domain, method, &error);
-       mono_error_cleanup (&error);
-       return result;
-}
-
-/**
- * mono_method_body_get_object_checked:
- * @domain: an app domain
- * @method: a method
- * @error: set on error
- *
- * Return an System.Reflection.MethodBody object representing the
- * method @method.  On failure, returns NULL and sets @error.
- */
-MonoReflectionMethodBody*
-mono_method_body_get_object_checked (MonoDomain *domain, MonoMethod *method, MonoError *error)
-{
-       MonoReflectionMethodBody *ret;
-       MonoMethodHeader *header;
-       MonoImage *image;
-       MonoReflectionType *rt;
-       guint32 method_rva, local_var_sig_token;
-       char *ptr;
-       unsigned char format, flags;
-       int i;
-
-       mono_error_init (error);
-
-       /* for compatibility with .net */
-       if (method_is_dynamic (method)) {
-               mono_error_set_generic_error (error, "System", "InvalidOperationException", "");
-               return NULL;
-       }
-
-       CHECK_OBJECT (MonoReflectionMethodBody *, method, NULL);
-
-       if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
-               (method->flags & METHOD_ATTRIBUTE_ABSTRACT) ||
-           (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
-               (method->klass->image->raw_data && method->klass->image->raw_data [1] != 'Z') ||
-           (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME))
-               return NULL;
-
-       image = method->klass->image;
-       header = mono_method_get_header_checked (method, error);
-       return_val_if_nok (error, NULL);
-
-       if (!image_is_dynamic (image)) {
-               /* Obtain local vars signature token */
-               method_rva = mono_metadata_decode_row_col (&image->tables [MONO_TABLE_METHOD], mono_metadata_token_index (method->token) - 1, MONO_METHOD_RVA);
-               ptr = mono_image_rva_map (image, method_rva);
-               flags = *(const unsigned char *) ptr;
-               format = flags & METHOD_HEADER_FORMAT_MASK;
-               switch (format){
-               case METHOD_HEADER_TINY_FORMAT:
-                       local_var_sig_token = 0;
-                       break;
-               case METHOD_HEADER_FAT_FORMAT:
-                       ptr += 2;
-                       ptr += 2;
-                       ptr += 4;
-                       local_var_sig_token = read32 (ptr);
-                       break;
-               default:
-                       g_assert_not_reached ();
-               }
-       } else
-               local_var_sig_token = 0; //FIXME
-
-       ret = (MonoReflectionMethodBody*)mono_object_new_checked (domain, mono_class_get_method_body_class (), error);
-       if (!is_ok (error))
-               goto fail;
-
-       ret->init_locals = header->init_locals;
-       ret->max_stack = header->max_stack;
-       ret->local_var_sig_token = local_var_sig_token;
-       MonoArray *il_arr = mono_array_new_cached (domain, mono_defaults.byte_class, header->code_size, error);
-       if (!is_ok (error))
-               goto fail;
-       MONO_OBJECT_SETREF (ret, il, il_arr);
-       memcpy (mono_array_addr (ret->il, guint8, 0), header->code, header->code_size);
-
-       /* Locals */
-       MonoArray *locals_arr = mono_array_new_cached (domain, mono_class_get_local_variable_info_class (), header->num_locals, error);
-       if (!is_ok (error))
-               goto fail;
-       MONO_OBJECT_SETREF (ret, locals, locals_arr);
-       for (i = 0; i < header->num_locals; ++i) {
-               MonoReflectionLocalVariableInfo *info = (MonoReflectionLocalVariableInfo*)mono_object_new_checked (domain, mono_class_get_local_variable_info_class (), error);
-               if (!is_ok (error))
-                       goto fail;
-
-               rt = mono_type_get_object_checked (domain, header->locals [i], error);
-               if (!is_ok (error))
-                       goto fail;
-
-               MONO_OBJECT_SETREF (info, local_type, rt);
-
-               info->is_pinned = header->locals [i]->pinned;
-               info->local_index = i;
-               mono_array_setref (ret->locals, i, info);
-       }
-
-       /* Exceptions */
-       MonoArray *exn_clauses = mono_array_new_cached (domain, mono_class_get_exception_handling_clause_class (), header->num_clauses, error);
-       if (!is_ok (error))
-               goto fail;
-       MONO_OBJECT_SETREF (ret, clauses, exn_clauses);
-       for (i = 0; i < header->num_clauses; ++i) {
-               MonoReflectionExceptionHandlingClause *info = (MonoReflectionExceptionHandlingClause*)mono_object_new_checked (domain, mono_class_get_exception_handling_clause_class (), error);
-               if (!is_ok (error))
-                       goto fail;
-               MonoExceptionClause *clause = &header->clauses [i];
-
-               info->flags = clause->flags;
-               info->try_offset = clause->try_offset;
-               info->try_length = clause->try_len;
-               info->handler_offset = clause->handler_offset;
-               info->handler_length = clause->handler_len;
-               if (clause->flags == MONO_EXCEPTION_CLAUSE_FILTER)
-                       info->filter_offset = clause->data.filter_offset;
-               else if (clause->data.catch_class) {
-                       rt = mono_type_get_object_checked (mono_domain_get (), &clause->data.catch_class->byval_arg, error);
-                       if (!is_ok (error))
-                               goto fail;
-
-                       MONO_OBJECT_SETREF (info, catch_type, rt);
-               }
-
-               mono_array_setref (ret->clauses, i, info);
-       }
-
-       mono_metadata_free_mh (header);
-       CACHE_OBJECT (MonoReflectionMethodBody *, method, ret, NULL);
-       return ret;
-
-fail:
-       mono_metadata_free_mh (header);
-       return NULL;
-}
-
-/**
- * mono_get_dbnull_object:
- * @domain: Domain where the object lives
- *
- * Returns the System.DBNull.Value singleton object
- *
- * Used as the value for ParameterInfo.DefaultValue 
- */
-MonoObject *
-mono_get_dbnull_object (MonoDomain *domain)
-{
-       MonoError error;
-       MonoObject *obj;
-       static MonoClassField *dbnull_value_field = NULL;
-       
-       if (!dbnull_value_field) {
-               MonoClass *dbnull_klass;
-               dbnull_klass = mono_class_get_dbnull_class ();
-               dbnull_value_field = mono_class_get_field_from_name (dbnull_klass, "Value");
-               g_assert (dbnull_value_field);
-       }
-       obj = mono_field_get_value_object_checked (domain, dbnull_value_field, NULL, &error);
-       mono_error_assert_ok (&error);
-       return obj;
-}
-
-static void
-get_default_param_value_blobs (MonoMethod *method, char **blobs, guint32 *types)
-{
-       guint32 param_index, i, lastp, crow = 0;
-       guint32 param_cols [MONO_PARAM_SIZE], const_cols [MONO_CONSTANT_SIZE];
-       gint32 idx;
-
-       MonoClass *klass = method->klass;
-       MonoImage *image = klass->image;
-       MonoMethodSignature *methodsig = mono_method_signature (method);
-
-       MonoTableInfo *constt;
-       MonoTableInfo *methodt;
-       MonoTableInfo *paramt;
-
-       if (!methodsig->param_count)
-               return;
-
-       mono_class_init (klass);
-
-       if (image_is_dynamic (klass->image)) {
-               MonoReflectionMethodAux *aux;
-               if (method->is_inflated)
-                       method = ((MonoMethodInflated*)method)->declaring;
-               aux = (MonoReflectionMethodAux *)g_hash_table_lookup (((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
-               if (aux && aux->param_defaults) {
-                       memcpy (blobs, &(aux->param_defaults [1]), methodsig->param_count * sizeof (char*));
-                       memcpy (types, &(aux->param_default_types [1]), methodsig->param_count * sizeof (guint32));
-               }
-               return;
-       }
-
-       methodt = &klass->image->tables [MONO_TABLE_METHOD];
-       paramt = &klass->image->tables [MONO_TABLE_PARAM];
-       constt = &image->tables [MONO_TABLE_CONSTANT];
-
-       idx = mono_method_get_index (method) - 1;
-       g_assert (idx != -1);
-
-       param_index = mono_metadata_decode_row_col (methodt, idx, MONO_METHOD_PARAMLIST);
-       if (idx + 1 < methodt->rows)
-               lastp = mono_metadata_decode_row_col (methodt, idx + 1, MONO_METHOD_PARAMLIST);
-       else
-               lastp = paramt->rows + 1;
-
-       for (i = param_index; i < lastp; ++i) {
-               guint32 paramseq;
-
-               mono_metadata_decode_row (paramt, i - 1, param_cols, MONO_PARAM_SIZE);
-               paramseq = param_cols [MONO_PARAM_SEQUENCE];
-
-               if (!(param_cols [MONO_PARAM_FLAGS] & PARAM_ATTRIBUTE_HAS_DEFAULT))
-                       continue;
-
-               crow = mono_metadata_get_constant_index (image, MONO_TOKEN_PARAM_DEF | i, crow + 1);
-               if (!crow) {
-                       continue;
-               }
-       
-               mono_metadata_decode_row (constt, crow - 1, const_cols, MONO_CONSTANT_SIZE);
-               blobs [paramseq - 1] = (char *)mono_metadata_blob_heap (image, const_cols [MONO_CONSTANT_VALUE]);
-               types [paramseq - 1] = const_cols [MONO_CONSTANT_TYPE];
-       }
-
-       return;
-}
-
-MonoObject *
-mono_get_object_from_blob (MonoDomain *domain, MonoType *type, const char *blob, MonoError *error)
-{
-       void *retval;
-       MonoClass *klass;
-       MonoObject *object;
-       MonoType *basetype = type;
-
-       mono_error_init (error);
-
-       if (!blob)
-               return NULL;
-       
-       klass = mono_class_from_mono_type (type);
-       if (klass->valuetype) {
-               object = mono_object_new_checked (domain, klass, error);
-               return_val_if_nok (error, NULL);
-               retval = ((gchar *) object + sizeof (MonoObject));
-               if (klass->enumtype)
-                       basetype = mono_class_enum_basetype (klass);
-       } else {
-               retval = &object;
-       }
-                       
-       if (!mono_get_constant_value_from_blob (domain, basetype->type,  blob, retval, error))
-               return object;
-       else
-               return NULL;
-}
-
-static int
-assembly_name_to_aname (MonoAssemblyName *assembly, char *p) {
-       int found_sep;
-       char *s;
-       gboolean quoted = FALSE;
-
-       memset (assembly, 0, sizeof (MonoAssemblyName));
-       assembly->culture = "";
-       memset (assembly->public_key_token, 0, MONO_PUBLIC_KEY_TOKEN_LENGTH);
-
-       if (*p == '"') {
-               quoted = TRUE;
-               p++;
-       }
-       assembly->name = p;
-       while (*p && (isalnum (*p) || *p == '.' || *p == '-' || *p == '_' || *p == '$' || *p == '@' || g_ascii_isspace (*p)))
-               p++;
-       if (quoted) {
-               if (*p != '"')
-                       return 1;
-               *p = 0;
-               p++;
-       }
-       if (*p != ',')
-               return 1;
-       *p = 0;
-       /* Remove trailing whitespace */
-       s = p - 1;
-       while (*s && g_ascii_isspace (*s))
-               *s-- = 0;
-       p ++;
-       while (g_ascii_isspace (*p))
-               p++;
-       while (*p) {
-               if (*p == 'V' && g_ascii_strncasecmp (p, "Version=", 8) == 0) {
-                       p += 8;
-                       assembly->major = strtoul (p, &s, 10);
-                       if (s == p || *s != '.')
-                               return 1;
-                       p = ++s;
-                       assembly->minor = strtoul (p, &s, 10);
-                       if (s == p || *s != '.')
-                               return 1;
-                       p = ++s;
-                       assembly->build = strtoul (p, &s, 10);
-                       if (s == p || *s != '.')
-                               return 1;
-                       p = ++s;
-                       assembly->revision = strtoul (p, &s, 10);
-                       if (s == p)
-                               return 1;
-                       p = s;
-               } else if (*p == 'C' && g_ascii_strncasecmp (p, "Culture=", 8) == 0) {
-                       p += 8;
-                       if (g_ascii_strncasecmp (p, "neutral", 7) == 0) {
-                               assembly->culture = "";
-                               p += 7;
-                       } else {
-                               assembly->culture = p;
-                               while (*p && *p != ',') {
-                                       p++;
-                               }
-                       }
-               } else if (*p == 'P' && g_ascii_strncasecmp (p, "PublicKeyToken=", 15) == 0) {
-                       p += 15;
-                       if (strncmp (p, "null", 4) == 0) {
-                               p += 4;
-                       } else {
-                               int len;
-                               gchar *start = p;
-                               while (*p && *p != ',') {
-                                       p++;
-                               }
-                               len = (p - start + 1);
-                               if (len > MONO_PUBLIC_KEY_TOKEN_LENGTH)
-                                       len = MONO_PUBLIC_KEY_TOKEN_LENGTH;
-                               g_strlcpy ((char*)assembly->public_key_token, start, len);
-                       }
-               } else {
-                       while (*p && *p != ',')
-                               p++;
-               }
-               found_sep = 0;
-               while (g_ascii_isspace (*p) || *p == ',') {
-                       *p++ = 0;
-                       found_sep = 1;
-                       continue;
-               }
-               /* failed */
-               if (!found_sep)
-                       return 1;
-       }
-
-       return 0;
-}
-
-/*
- * mono_reflection_parse_type:
- * @name: type name
- *
- * Parse a type name as accepted by the GetType () method and output the info
- * extracted in the info structure.
- * the name param will be mangled, so, make a copy before passing it to this function.
- * The fields in info will be valid until the memory pointed to by name is valid.
- *
- * See also mono_type_get_name () below.
- *
- * Returns: 0 on parse error.
- */
-static int
-_mono_reflection_parse_type (char *name, char **endptr, gboolean is_recursed,
-                            MonoTypeNameParse *info)
-{
-       char *start, *p, *w, *last_point, *startn;
-       int in_modifiers = 0;
-       int isbyref = 0, rank = 0, isptr = 0;
-
-       start = p = w = name;
-
-       //FIXME could we just zero the whole struct? memset (&info, 0, sizeof (MonoTypeNameParse))
-       memset (&info->assembly, 0, sizeof (MonoAssemblyName));
-       info->name = info->name_space = NULL;
-       info->nested = NULL;
-       info->modifiers = NULL;
-       info->type_arguments = NULL;
-
-       /* last_point separates the namespace from the name */
-       last_point = NULL;
-       /* Skips spaces */
-       while (*p == ' ') p++, start++, w++, name++;
-
-       while (*p) {
-               switch (*p) {
-               case '+':
-                       *p = 0; /* NULL terminate the name */
-                       startn = p + 1;
-                       info->nested = g_list_append (info->nested, startn);
-                       /* we have parsed the nesting namespace + name */
-                       if (info->name)
-                               break;
-                       if (last_point) {
-                               info->name_space = start;
-                               *last_point = 0;
-                               info->name = last_point + 1;
-                       } else {
-                               info->name_space = (char *)"";
-                               info->name = start;
-                       }
-                       break;
-               case '.':
-                       last_point = p;
-                       break;
-               case '\\':
-                       ++p;
-                       break;
-               case '&':
-               case '*':
-               case '[':
-               case ',':
-               case ']':
-                       in_modifiers = 1;
-                       break;
-               default:
-                       break;
-               }
-               if (in_modifiers)
-                       break;
-               // *w++ = *p++;
-               p++;
-       }
-       
-       if (!info->name) {
-               if (last_point) {
-                       info->name_space = start;
-                       *last_point = 0;
-                       info->name = last_point + 1;
-               } else {
-                       info->name_space = (char *)"";
-                       info->name = start;
-               }
-       }
-       while (*p) {
-               switch (*p) {
-               case '&':
-                       if (isbyref) /* only one level allowed by the spec */
-                               return 0;
-                       isbyref = 1;
-                       isptr = 0;
-                       info->modifiers = g_list_append (info->modifiers, GUINT_TO_POINTER (0));
-                       *p++ = 0;
-                       break;
-               case '*':
-                       if (isbyref) /* pointer to ref not okay */
-                               return 0;
-                       info->modifiers = g_list_append (info->modifiers, GUINT_TO_POINTER (-1));
-                       isptr = 1;
-                       *p++ = 0;
-                       break;
-               case '[':
-                       if (isbyref) /* array of ref and generic ref are not okay */
-                               return 0;
-                       //Decide if it's an array of a generic argument list
-                       *p++ = 0;
-
-                       if (!*p) //XXX test
-                               return 0;
-                       if (*p  == ',' || *p == '*' || *p == ']') { //array
-                               isptr = 0;
-                               rank = 1;
-                               while (*p) {
-                                       if (*p == ']')
-                                               break;
-                                       if (*p == ',')
-                                               rank++;
-                                       else if (*p == '*') /* '*' means unknown lower bound */
-                                               info->modifiers = g_list_append (info->modifiers, GUINT_TO_POINTER (-2));
-                                       else
-                                               return 0;
-                                       ++p;
-                               }
-                               if (*p++ != ']')
-                                       return 0;
-                               info->modifiers = g_list_append (info->modifiers, GUINT_TO_POINTER (rank));
-                       } else {
-                               if (rank || isptr) /* generic args after array spec or ptr*/ //XXX test
-                                       return 0;
-                               isptr = 0;
-                               info->type_arguments = g_ptr_array_new ();
-                               while (*p) {
-                                       MonoTypeNameParse *subinfo = g_new0 (MonoTypeNameParse, 1);
-                                       gboolean fqname = FALSE;
-
-                                       g_ptr_array_add (info->type_arguments, subinfo);
-
-                                       while (*p == ' ') p++;
-                                       if (*p == '[') {
-                                               p++;
-                                               fqname = TRUE;
-                                       }
-
-                                       if (!_mono_reflection_parse_type (p, &p, TRUE, subinfo))
-                                               return 0;
-
-                                       /*MS is lenient on [] delimited parameters that aren't fqn - and F# uses them.*/
-                                       if (fqname && (*p != ']')) {
-                                               char *aname;
-
-                                               if (*p != ',')
-                                                       return 0;
-                                               *p++ = 0;
-
-                                               aname = p;
-                                               while (*p && (*p != ']'))
-                                                       p++;
-
-                                               if (*p != ']')
-                                                       return 0;
-
-                                               *p++ = 0;
-                                               while (*aname) {
-                                                       if (g_ascii_isspace (*aname)) {
-                                                               ++aname;
-                                                               continue;
-                                                       }
-                                                       break;
-                                               }
-                                               if (!*aname ||
-                                                   !assembly_name_to_aname (&subinfo->assembly, aname))
-                                                       return 0;
-                                       } else if (fqname && (*p == ']')) {
-                                               *p++ = 0;
-                                       }
-                                       if (*p == ']') {
-                                               *p++ = 0;
-                                               break;
-                                       } else if (!*p) {
-                                               return 0;
-                                       }
-                                       *p++ = 0;
-                               }
-                       }
-                       break;
-               case ']':
-                       if (is_recursed)
-                               goto end;
-                       return 0;
-               case ',':
-                       if (is_recursed)
-                               goto end;
-                       *p++ = 0;
-                       while (*p) {
-                               if (g_ascii_isspace (*p)) {
-                                       ++p;
-                                       continue;
-                               }
-                               break;
-                       }
-                       if (!*p)
-                               return 0; /* missing assembly name */
-                       if (!assembly_name_to_aname (&info->assembly, p))
-                               return 0;
-                       break;
-               default:
-                       return 0;
-               }
-               if (info->assembly.name)
-                       break;
-       }
-       // *w = 0; /* terminate class name */
- end:
-       if (!info->name || !*info->name)
-               return 0;
-       if (endptr)
-               *endptr = p;
-       /* add other consistency checks */
-       return 1;
-}
-
-
-/**
- * mono_identifier_unescape_type_name_chars:
- * @identifier: the display name of a mono type
- *
- * Returns:
- *  The name in internal form, that is without escaping backslashes.
- *
- *  The string is modified in place!
- */
-char*
-mono_identifier_unescape_type_name_chars(char* identifier)
-{
-       char *w, *r;
-       if (!identifier)
-               return NULL;
-       for (w = r = identifier; *r != 0; r++)
-       {
-               char c = *r;
-               if (c == '\\') {
-                       r++;
-                       if (*r == 0)
-                               break;
-                       c = *r;
-               }
-               *w = c;
-               w++;
-       }
-       if (w != r)
-               *w = 0;
-       return identifier;
-}
-
-void
-mono_identifier_unescape_info (MonoTypeNameParse* info);
-
-static void
-unescape_each_type_argument(void* data, void* user_data)
-{
-       MonoTypeNameParse* info = (MonoTypeNameParse*)data;
-       mono_identifier_unescape_info (info);
-}
-
-static void
-unescape_each_nested_name (void* data, void* user_data)
-{
-       char* nested_name = (char*) data;
-       mono_identifier_unescape_type_name_chars(nested_name);
-}
-
-/**
- * mono_identifier_unescape_info:
- *
- * @info: a parsed display form of an (optionally assembly qualified) full type name.
- *
- * Returns: nothing.
- *
- * Destructively updates the info by unescaping the identifiers that
- * comprise the type namespace, name, nested types (if any) and
- * generic type arguments (if any).
- *
- * The resulting info has the names in internal form.
- *
- */
-void
-mono_identifier_unescape_info (MonoTypeNameParse *info)
-{
-       if (!info)
-               return;
-       mono_identifier_unescape_type_name_chars(info->name_space);
-       mono_identifier_unescape_type_name_chars(info->name);
-       // but don't escape info->assembly
-       if (info->type_arguments)
-               g_ptr_array_foreach(info->type_arguments, &unescape_each_type_argument, NULL);
-       if (info->nested)
-               g_list_foreach(info->nested, &unescape_each_nested_name, NULL);
-}
-
-int
-mono_reflection_parse_type (char *name, MonoTypeNameParse *info)
-{
-       int ok = _mono_reflection_parse_type (name, NULL, FALSE, info);
-       if (ok) {
-               mono_identifier_unescape_info (info);
-       }
-       return ok;
-}
-
-static MonoType*
-_mono_reflection_get_type_from_info (MonoTypeNameParse *info, MonoImage *image, gboolean ignorecase, MonoError *error)
-{
-       gboolean type_resolve = FALSE;
-       MonoType *type;
-       MonoImage *rootimage = image;
-
-       mono_error_init (error);
-
-       if (info->assembly.name) {
-               MonoAssembly *assembly = mono_assembly_loaded (&info->assembly);
-               if (!assembly && image && image->assembly && mono_assembly_names_equal (&info->assembly, &image->assembly->aname))
-                       /* 
-                        * This could happen in the AOT compiler case when the search hook is not
-                        * installed.
-                        */
-                       assembly = image->assembly;
-               if (!assembly) {
-                       /* then we must load the assembly ourselve - see #60439 */
-                       assembly = mono_assembly_load (&info->assembly, image->assembly->basedir, NULL);
-                       if (!assembly)
-                               return NULL;
-               }
-               image = assembly->image;
-       } else if (!image) {
-               image = mono_defaults.corlib;
-       }
-
-       type = mono_reflection_get_type_with_rootimage (rootimage, image, info, ignorecase, &type_resolve, error);
-       if (type == NULL && !info->assembly.name && image != mono_defaults.corlib) {
-               /* ignore the error and try again */
-               mono_error_cleanup (error);
-               mono_error_init (error);
-               image = mono_defaults.corlib;
-               type = mono_reflection_get_type_with_rootimage (rootimage, image, info, ignorecase, &type_resolve, error);
-       }
-
-       return type;
-}
-
-/**
- * mono_reflection_get_type_internal:
- *
- * Returns: may return NULL on success, sets error on failure.
- */
-static MonoType*
-mono_reflection_get_type_internal (MonoImage *rootimage, MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, MonoError *error)
-{
-       MonoClass *klass;
-       GList *mod;
-       int modval;
-       gboolean bounded = FALSE;
-       
-       mono_error_init (error);
-       if (!image)
-               image = mono_defaults.corlib;
-
-       if (!rootimage)
-               rootimage = mono_defaults.corlib;
-
-       if (ignorecase)
-               klass = mono_class_from_name_case_checked (image, info->name_space, info->name, error);
-       else
-               klass = mono_class_from_name_checked (image, info->name_space, info->name, error);
-
-       if (!klass)
-               return NULL;
-
-       for (mod = info->nested; mod; mod = mod->next) {
-               gpointer iter = NULL;
-               MonoClass *parent;
-
-               parent = klass;
-               mono_class_init (parent);
-
-               while ((klass = mono_class_get_nested_types (parent, &iter))) {
-                       char *lastp;
-                       char *nested_name, *nested_nspace;
-                       gboolean match = TRUE;
-
-                       lastp = strrchr ((const char *)mod->data, '.');
-                       if (lastp) {
-                               /* Nested classes can have namespaces */
-                               int nspace_len;
-
-                               nested_name = g_strdup (lastp + 1);
-                               nspace_len = lastp - (char*)mod->data;
-                               nested_nspace = (char *)g_malloc (nspace_len + 1);
-                               memcpy (nested_nspace, mod->data, nspace_len);
-                               nested_nspace [nspace_len] = '\0';
-
-                       } else {
-                               nested_name = (char *)mod->data;
-                               nested_nspace = NULL;
-                       }
-
-                       if (nested_nspace) {
-                               if (ignorecase) {
-                                       if (!(klass->name_space && mono_utf8_strcasecmp (klass->name_space, nested_nspace) == 0))
-                                               match = FALSE;
-                               } else {
-                                       if (!(klass->name_space && strcmp (klass->name_space, nested_nspace) == 0))
-                                               match = FALSE;
-                               }
-                       }
-                       if (match) {
-                               if (ignorecase) {
-                                       if (mono_utf8_strcasecmp (klass->name, nested_name) != 0)
-                                               match = FALSE;
-                               } else {
-                                       if (strcmp (klass->name, nested_name) != 0)
-                                               match = FALSE;
-                               }
-                       }
-                       if (lastp) {
-                               g_free (nested_name);
-                               g_free (nested_nspace);
-                       }
-                       if (match)
-                               break;
-               }
-
-               if (!klass)
-                       break;
-       }
-       if (!klass)
-               return NULL;
-
-       if (info->type_arguments) {
-               MonoType **type_args = g_new0 (MonoType *, info->type_arguments->len);
-               MonoReflectionType *the_type;
-               MonoType *instance;
-               int i;
-
-               for (i = 0; i < info->type_arguments->len; i++) {
-                       MonoTypeNameParse *subinfo = (MonoTypeNameParse *)g_ptr_array_index (info->type_arguments, i);
-
-                       type_args [i] = _mono_reflection_get_type_from_info (subinfo, rootimage, ignorecase, error);
-                       if (!type_args [i]) {
-                               g_free (type_args);
-                               return NULL;
-                       }
-               }
-
-               the_type = mono_type_get_object_checked (mono_domain_get (), &klass->byval_arg, error);
-               if (!the_type)
-                       return NULL;
-
-               instance = mono_reflection_bind_generic_parameters (
-                       the_type, info->type_arguments->len, type_args, error);
-
-               g_free (type_args);
-               if (!instance)
-                       return NULL;
-
-               klass = mono_class_from_mono_type (instance);
-       }
-
-       for (mod = info->modifiers; mod; mod = mod->next) {
-               modval = GPOINTER_TO_UINT (mod->data);
-               if (!modval) { /* byref: must be last modifier */
-                       return &klass->this_arg;
-               } else if (modval == -1) {
-                       klass = mono_ptr_class_get (&klass->byval_arg);
-               } else if (modval == -2) {
-                       bounded = TRUE;
-               } else { /* array rank */
-                       klass = mono_bounded_array_class_get (klass, modval, bounded);
-               }
-       }
-
-       return &klass->byval_arg;
-}
-
-/*
- * mono_reflection_get_type:
- * @image: a metadata context
- * @info: type description structure
- * @ignorecase: flag for case-insensitive string compares
- * @type_resolve: whenever type resolve was already tried
- *
- * Build a MonoType from the type description in @info.
- * 
- */
-
-MonoType*
-mono_reflection_get_type (MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve) {
-       MonoError error;
-       MonoType *result = mono_reflection_get_type_with_rootimage (image, image, info, ignorecase, type_resolve, &error);
-       mono_error_cleanup (&error);
-       return result;
-}
-
-/**
- * mono_reflection_get_type_checked:
- * @rootimage: the image of the currently active managed caller
- * @image: a metadata context
- * @info: type description structure
- * @ignorecase: flag for case-insensitive string compares
- * @type_resolve: whenever type resolve was already tried
- * @error: set on error.
- *
- * Build a MonoType from the type description in @info. On failure returns NULL and sets @error.
- *
- */
-MonoType*
-mono_reflection_get_type_checked (MonoImage *rootimage, MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve, MonoError *error) {
-       mono_error_init (error);
-       return mono_reflection_get_type_with_rootimage (rootimage, image, info, ignorecase, type_resolve, error);
-}
-
-
-static MonoType*
-mono_reflection_get_type_internal_dynamic (MonoImage *rootimage, MonoAssembly *assembly, MonoTypeNameParse *info, gboolean ignorecase, MonoError *error)
-{
-       MonoReflectionAssemblyBuilder *abuilder;
-       MonoType *type;
-       int i;
-
-       mono_error_init (error);
-       g_assert (assembly_is_dynamic (assembly));
-       abuilder = (MonoReflectionAssemblyBuilder*)mono_assembly_get_object_checked (((MonoDynamicAssembly*)assembly)->domain, assembly, error);
-       if (!abuilder)
-               return NULL;
-
-       /* Enumerate all modules */
-
-       type = NULL;
-       if (abuilder->modules) {
-               for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
-                       MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
-                       type = mono_reflection_get_type_internal (rootimage, &mb->dynamic_image->image, info, ignorecase, error);
-                       if (type)
-                               break;
-                       if (!mono_error_ok (error))
-                               return NULL;
-               }
-       }
-
-       if (!type && abuilder->loaded_modules) {
-               for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
-                       MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
-                       type = mono_reflection_get_type_internal (rootimage, mod->image, info, ignorecase, error);
-                       if (type)
-                               break;
-                       if (!mono_error_ok (error))
-                               return NULL;
-               }
-       }
-
-       return type;
-}
-       
-MonoType*
-mono_reflection_get_type_with_rootimage (MonoImage *rootimage, MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve, MonoError *error)
-{
-       MonoType *type;
-       MonoReflectionAssembly *assembly;
-       GString *fullName;
-       GList *mod;
-
-       mono_error_init (error);
-
-       if (image && image_is_dynamic (image))
-               type = mono_reflection_get_type_internal_dynamic (rootimage, image->assembly, info, ignorecase, error);
-       else {
-               type = mono_reflection_get_type_internal (rootimage, image, info, ignorecase, error);
-       }
-       return_val_if_nok (error, NULL);
-
-       if (type)
-               return type;
-       if (!mono_domain_has_type_resolve (mono_domain_get ()))
-               return NULL;
-
-       if (type_resolve) {
-               if (*type_resolve) 
-                       return NULL;
-               else
-                       *type_resolve = TRUE;
-       }
-       
-       /* Reconstruct the type name */
-       fullName = g_string_new ("");
-       if (info->name_space && (info->name_space [0] != '\0'))
-               g_string_printf (fullName, "%s.%s", info->name_space, info->name);
-       else
-               g_string_printf (fullName, "%s", info->name);
-       for (mod = info->nested; mod; mod = mod->next)
-               g_string_append_printf (fullName, "+%s", (char*)mod->data);
-
-       assembly = mono_domain_try_type_resolve_checked ( mono_domain_get (), fullName->str, NULL, error);
-       if (!is_ok (error)) {
-               g_string_free (fullName, TRUE);
-               return NULL;
-       }
-
-       if (assembly) {
-               if (assembly_is_dynamic (assembly->assembly))
-                       type = mono_reflection_get_type_internal_dynamic (rootimage, assembly->assembly,
-                                                                         info, ignorecase, error);
-               else
-                       type = mono_reflection_get_type_internal (rootimage, assembly->assembly->image, 
-                                                                 info, ignorecase, error);
-       }
-       g_string_free (fullName, TRUE);
-       return_val_if_nok (error, NULL);
-       return type;
-}
-
-void
-mono_reflection_free_type_info (MonoTypeNameParse *info)
-{
-       g_list_free (info->modifiers);
-       g_list_free (info->nested);
-
-       if (info->type_arguments) {
-               int i;
-
-               for (i = 0; i < info->type_arguments->len; i++) {
-                       MonoTypeNameParse *subinfo = (MonoTypeNameParse *)g_ptr_array_index (info->type_arguments, i);
-
-                       mono_reflection_free_type_info (subinfo);
-                       /*We free the subinfo since it is allocated by _mono_reflection_parse_type*/
-                       g_free (subinfo);
-               }
-
-               g_ptr_array_free (info->type_arguments, TRUE);
-       }
-}
-
-/*
- * mono_reflection_type_from_name:
- * @name: type name.
- * @image: a metadata context (can be NULL).
- *
- * Retrieves a MonoType from its @name. If the name is not fully qualified,
- * it defaults to get the type from @image or, if @image is NULL or loading
- * from it fails, uses corlib.
- * 
- */
-MonoType*
-mono_reflection_type_from_name (char *name, MonoImage *image)
-{
-       MonoError error;
-       MonoType  *result = mono_reflection_type_from_name_checked (name, image, &error);
-       mono_error_cleanup (&error);
-       return result;
-}
-
-/**
- * mono_reflection_type_from_name_checked:
- * @name: type name.
- * @image: a metadata context (can be NULL).
- * @error: set on errror.
- *
- * Retrieves a MonoType from its @name. If the name is not fully qualified,
- * it defaults to get the type from @image or, if @image is NULL or loading
- * from it fails, uses corlib.  On failure returns NULL and sets @error.
- * 
- */
-MonoType*
-mono_reflection_type_from_name_checked (char *name, MonoImage *image, MonoError *error)
-{
-       MonoType *type = NULL;
-       MonoTypeNameParse info;
-       char *tmp;
-
-       mono_error_init (error);
-       /* Make a copy since parse_type modifies its argument */
-       tmp = g_strdup (name);
-       
-       /*g_print ("requested type %s\n", str);*/
-       if (mono_reflection_parse_type (tmp, &info)) {
-               type = _mono_reflection_get_type_from_info (&info, image, FALSE, error);
-               if (!is_ok (error)) {
-                       g_free (tmp);
-                       mono_reflection_free_type_info (&info);
-                       return NULL;
-               }
-       }
-
-       g_free (tmp);
-       mono_reflection_free_type_info (&info);
-       return type;
-}
-
-/*
- * mono_reflection_get_token:
- *
- *   Return the metadata token of OBJ which should be an object
- * representing a metadata element.
- */
-guint32
-mono_reflection_get_token (MonoObject *obj)
-{
-       MonoError error;
-       guint32 result = mono_reflection_get_token_checked (obj, &error);
-       mono_error_assert_ok (&error);
-       return result;
-}
-
-/**
- * mono_reflection_get_token_checked:
- * @obj: the object
- * @error: set on error
- *
- *   Return the metadata token of @obj which should be an object
- * representing a metadata element.  On failure sets @error.
- */
-guint32
-mono_reflection_get_token_checked (MonoObject *obj, MonoError *error)
-{
-       MonoClass *klass;
-       guint32 token = 0;
-
-       mono_error_init (error);
-
-       klass = obj->vtable->klass;
-
-       if (strcmp (klass->name, "MethodBuilder") == 0) {
-               MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
-
-               token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
-       } else if (strcmp (klass->name, "ConstructorBuilder") == 0) {
-               MonoReflectionCtorBuilder *mb = (MonoReflectionCtorBuilder *)obj;
-
-               token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
-       } else if (strcmp (klass->name, "FieldBuilder") == 0) {
-               MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)obj;
-
-               token = fb->table_idx | MONO_TOKEN_FIELD_DEF;
-       } else if (strcmp (klass->name, "TypeBuilder") == 0) {
-               MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)obj;
-               token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
-       } else if (strcmp (klass->name, "RuntimeType") == 0) {
-               MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
-               return_val_if_nok (error, 0);
-               MonoClass *mc = mono_class_from_mono_type (type);
-               if (!mono_class_init (mc)) {
-                       mono_error_set_for_class_failure (error, mc);
-                       return 0;
-               }
-
-               token = mc->type_token;
-       } else if (strcmp (klass->name, "MonoCMethod") == 0 ||
-                  strcmp (klass->name, "MonoMethod") == 0 ||
-                  strcmp (klass->name, "MonoGenericMethod") == 0 ||
-                  strcmp (klass->name, "MonoGenericCMethod") == 0) {
-               MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
-               if (m->method->is_inflated) {
-                       MonoMethodInflated *inflated = (MonoMethodInflated *) m->method;
-                       return inflated->declaring->token;
-               } else {
-                       token = m->method->token;
-               }
-       } else if (strcmp (klass->name, "MonoField") == 0) {
-               MonoReflectionField *f = (MonoReflectionField*)obj;
-
-               if (is_field_on_inst (f->field)) {
-                       MonoDynamicGenericClass *dgclass = (MonoDynamicGenericClass*)f->field->parent->generic_class;
-
-                       if (f->field >= dgclass->fields && f->field < dgclass->fields + dgclass->count_fields) {
-                               int field_index = f->field - dgclass->fields;
-                               MonoObject *obj;
-
-                               g_assert (field_index >= 0 && field_index < dgclass->count_fields);
-                               obj = dgclass->field_objects [field_index];
-                               return mono_reflection_get_token_checked (obj, error);
-                       }
-               }
-               token = mono_class_get_field_token (f->field);
-       } else if (strcmp (klass->name, "MonoProperty") == 0) {
-               MonoReflectionProperty *p = (MonoReflectionProperty*)obj;
-
-               token = mono_class_get_property_token (p->property);
-       } else if (strcmp (klass->name, "MonoEvent") == 0) {
-               MonoReflectionMonoEvent *p = (MonoReflectionMonoEvent*)obj;
-
-               token = mono_class_get_event_token (p->event);
-       } else if (strcmp (klass->name, "ParameterInfo") == 0 || strcmp (klass->name, "MonoParameterInfo") == 0) {
-               MonoReflectionParameter *p = (MonoReflectionParameter*)obj;
-               MonoClass *member_class = mono_object_class (p->MemberImpl);
-               g_assert (mono_class_is_reflection_method_or_constructor (member_class));
-
-               token = mono_method_get_param_token (((MonoReflectionMethod*)p->MemberImpl)->method, p->PositionImpl);
-       } else if (strcmp (klass->name, "Module") == 0 || strcmp (klass->name, "MonoModule") == 0) {
-               MonoReflectionModule *m = (MonoReflectionModule*)obj;
-
-               token = m->token;
-       } else if (strcmp (klass->name, "Assembly") == 0 || strcmp (klass->name, "MonoAssembly") == 0) {
-               token = mono_metadata_make_token (MONO_TABLE_ASSEMBLY, 1);
-       } else {
-               mono_error_set_not_implemented (error, "MetadataToken is not supported for type '%s.%s'",
-                                               klass->name_space, klass->name);
-               return 0;
-       }
-
-       return token;
-}
-
-/*
- * Load the type with name @n on behalf of image @image.  On failure sets @error and returns NULL.
- * The @is_enum flag only affects the error message that's displayed on failure.
- */
-static MonoType*
-cattr_type_from_name (char *n, MonoImage *image, gboolean is_enum, MonoError *error)
-{
-       MonoError inner_error;
-       MonoType *t = mono_reflection_type_from_name_checked (n, image, &inner_error);
-       if (!t) {
-               mono_error_set_type_load_name (error, g_strdup(n), NULL,
-                                              "Could not load %s %s while decoding custom attribute: %s",
-                                              is_enum ? "enum type": "type",
-                                              n,
-                                              mono_error_get_message (&inner_error));
-               mono_error_cleanup (&inner_error);
-               return NULL;
-       }
-       return t;
-}
-
-static MonoClass*
-load_cattr_enum_type (MonoImage *image, const char *p, const char **end, MonoError *error)
-{
-       char *n;
-       MonoType *t;
-       int slen = mono_metadata_decode_value (p, &p);
-
-       mono_error_init (error);
-
-       n = (char *)g_memdup (p, slen + 1);
-       n [slen] = 0;
-       t = cattr_type_from_name (n, image, TRUE, error);
-       g_free (n);
-       return_val_if_nok (error, NULL);
-       p += slen;
-       *end = p;
-       return mono_class_from_mono_type (t);
-}
-
-static void*
-load_cattr_value (MonoImage *image, MonoType *t, const char *p, const char **end, MonoError *error)
-{
-       int slen, type = t->type;
-       MonoClass *tklass = t->data.klass;
-
-       mono_error_init (error);
-
-handle_enum:
-       switch (type) {
-       case MONO_TYPE_U1:
-       case MONO_TYPE_I1:
-       case MONO_TYPE_BOOLEAN: {
-               MonoBoolean *bval = (MonoBoolean *)g_malloc (sizeof (MonoBoolean));
-               *bval = *p;
-               *end = p + 1;
-               return bval;
-       }
-       case MONO_TYPE_CHAR:
-       case MONO_TYPE_U2:
-       case MONO_TYPE_I2: {
-               guint16 *val = (guint16 *)g_malloc (sizeof (guint16));
-               *val = read16 (p);
-               *end = p + 2;
-               return val;
-       }
-#if SIZEOF_VOID_P == 4
-       case MONO_TYPE_U:
-       case MONO_TYPE_I:
-#endif
-       case MONO_TYPE_R4:
-       case MONO_TYPE_U4:
-       case MONO_TYPE_I4: {
-               guint32 *val = (guint32 *)g_malloc (sizeof (guint32));
-               *val = read32 (p);
-               *end = p + 4;
-               return val;
-       }
-#if SIZEOF_VOID_P == 8
-       case MONO_TYPE_U: /* error out instead? this should probably not happen */
-       case MONO_TYPE_I:
-#endif
-       case MONO_TYPE_U8:
-       case MONO_TYPE_I8: {
-               guint64 *val = (guint64 *)g_malloc (sizeof (guint64));
-               *val = read64 (p);
-               *end = p + 8;
-               return val;
-       }
-       case MONO_TYPE_R8: {
-               double *val = (double *)g_malloc (sizeof (double));
-               readr8 (p, val);
-               *end = p + 8;
-               return val;
-       }
-       case MONO_TYPE_VALUETYPE:
-               if (t->data.klass->enumtype) {
-                       type = mono_class_enum_basetype (t->data.klass)->type;
-                       goto handle_enum;
-               } else {
-                       MonoClass *k =  t->data.klass;
-                       
-                       if (mono_is_corlib_image (k->image) && strcmp (k->name_space, "System") == 0 && strcmp (k->name, "DateTime") == 0){
-                               guint64 *val = (guint64 *)g_malloc (sizeof (guint64));
-                               *val = read64 (p);
-                               *end = p + 8;
-                               return val;
-                       }
-               }
-               g_error ("generic valutype %s not handled in custom attr value decoding", t->data.klass->name);
-               break;
-               
-       case MONO_TYPE_STRING:
-               if (*p == (char)0xFF) {
-                       *end = p + 1;
-                       return NULL;
-               }
-               slen = mono_metadata_decode_value (p, &p);
-               *end = p + slen;
-               return mono_string_new_len_checked (mono_domain_get (), p, slen, error);
-       case MONO_TYPE_CLASS: {
-               MonoReflectionType *rt;
-               char *n;
-               MonoType *t;
-               if (*p == (char)0xFF) {
-                       *end = p + 1;
-                       return NULL;
-               }
-handle_type:
-               slen = mono_metadata_decode_value (p, &p);
-               n = (char *)g_memdup (p, slen + 1);
-               n [slen] = 0;
-               t = cattr_type_from_name (n, image, FALSE, error);
-               g_free (n);
-               return_val_if_nok (error, NULL);
-               *end = p + slen;
-
-               rt = mono_type_get_object_checked (mono_domain_get (), t, error);
-               if (!mono_error_ok (error))
-                       return NULL;
-
-               return rt;
-       }
-       case MONO_TYPE_OBJECT: {
-               char subt = *p++;
-               MonoObject *obj;
-               MonoClass *subc = NULL;
-               void *val;
-
-               if (subt == 0x50) {
-                       goto handle_type;
-               } else if (subt == 0x0E) {
-                       type = MONO_TYPE_STRING;
-                       goto handle_enum;
-               } else if (subt == 0x1D) {
-                       MonoType simple_type = {{0}};
-                       int etype = *p;
-                       p ++;
-
-                       type = MONO_TYPE_SZARRAY;
-                       if (etype == 0x50) {
-                               tklass = mono_defaults.systemtype_class;
-                       } else if (etype == 0x55) {
-                               tklass = load_cattr_enum_type (image, p, &p, error);
-                               if (!mono_error_ok (error))
-                                       return NULL;
-                       } else {
-                               if (etype == 0x51)
-                                       /* See Partition II, Appendix B3 */
-                                       etype = MONO_TYPE_OBJECT;
-                               simple_type.type = (MonoTypeEnum)etype;
-                               tklass = mono_class_from_mono_type (&simple_type);
-                       }
-                       goto handle_enum;
-               } else if (subt == 0x55) {
-                       char *n;
-                       MonoType *t;
-                       slen = mono_metadata_decode_value (p, &p);
-                       n = (char *)g_memdup (p, slen + 1);
-                       n [slen] = 0;
-                       t = cattr_type_from_name (n, image, FALSE, error);
-                       g_free (n);
-                       return_val_if_nok (error, NULL);
-                       p += slen;
-                       subc = mono_class_from_mono_type (t);
-               } else if (subt >= MONO_TYPE_BOOLEAN && subt <= MONO_TYPE_R8) {
-                       MonoType simple_type = {{0}};
-                       simple_type.type = (MonoTypeEnum)subt;
-                       subc = mono_class_from_mono_type (&simple_type);
-               } else {
-                       g_error ("Unknown type 0x%02x for object type encoding in custom attr", subt);
-               }
-               val = load_cattr_value (image, &subc->byval_arg, p, end, error);
-               obj = NULL;
-               if (mono_error_ok (error)) {
-                       obj = mono_object_new_checked (mono_domain_get (), subc, error);
-                       g_assert (!subc->has_references);
-                       if (mono_error_ok (error))
-                               mono_gc_memmove_atomic ((char*)obj + sizeof (MonoObject), val, mono_class_value_size (subc, NULL));
-               }
-
-               g_free (val);
-               return obj;
-       }
-       case MONO_TYPE_SZARRAY: {
-               MonoArray *arr;
-               guint32 i, alen, basetype;
-               alen = read32 (p);
-               p += 4;
-               if (alen == 0xffffffff) {
-                       *end = p;
-                       return NULL;
-               }
-               arr = mono_array_new_checked (mono_domain_get(), tklass, alen, error);
-               return_val_if_nok (error, NULL);
-               basetype = tklass->byval_arg.type;
-               if (basetype == MONO_TYPE_VALUETYPE && tklass->enumtype)
-                       basetype = mono_class_enum_basetype (tklass)->type;
-               switch (basetype)
-               {
-                       case MONO_TYPE_U1:
-                       case MONO_TYPE_I1:
-                       case MONO_TYPE_BOOLEAN:
-                               for (i = 0; i < alen; i++) {
-                                       MonoBoolean val = *p++;
-                                       mono_array_set (arr, MonoBoolean, i, val);
-                               }
-                               break;
-                       case MONO_TYPE_CHAR:
-                       case MONO_TYPE_U2:
-                       case MONO_TYPE_I2:
-                               for (i = 0; i < alen; i++) {
-                                       guint16 val = read16 (p);
-                                       mono_array_set (arr, guint16, i, val);
-                                       p += 2;
-                               }
-                               break;
-                       case MONO_TYPE_R4:
-                       case MONO_TYPE_U4:
-                       case MONO_TYPE_I4:
-                               for (i = 0; i < alen; i++) {
-                                       guint32 val = read32 (p);
-                                       mono_array_set (arr, guint32, i, val);
-                                       p += 4;
-                               }
-                               break;
-                       case MONO_TYPE_R8:
-                               for (i = 0; i < alen; i++) {
-                                       double val;
-                                       readr8 (p, &val);
-                                       mono_array_set (arr, double, i, val);
-                                       p += 8;
-                               }
-                               break;
-                       case MONO_TYPE_U8:
-                       case MONO_TYPE_I8:
-                               for (i = 0; i < alen; i++) {
-                                       guint64 val = read64 (p);
-                                       mono_array_set (arr, guint64, i, val);
-                                       p += 8;
-                               }
-                               break;
-                       case MONO_TYPE_CLASS:
-                       case MONO_TYPE_OBJECT:
-                       case MONO_TYPE_STRING:
-                       case MONO_TYPE_SZARRAY:
-                               for (i = 0; i < alen; i++) {
-                                       MonoObject *item = (MonoObject *)load_cattr_value (image, &tklass->byval_arg, p, &p, error);
-                                       if (!mono_error_ok (error))
-                                               return NULL;
-                                       mono_array_setref (arr, i, item);
-                               }
-                               break;
-                       default:
-                               g_error ("Type 0x%02x not handled in custom attr array decoding", basetype);
-               }
-               *end=p;
-               return arr;
-       }
-       default:
-               g_error ("Type 0x%02x not handled in custom attr value decoding", type);
-       }
-       return NULL;
-}
-
-static MonoObject*
-load_cattr_value_boxed (MonoDomain *domain, MonoImage *image, MonoType *t, const char* p, const char** end, MonoError *error)
-{
-       mono_error_init (error);
-
-       gboolean is_ref = type_is_reference (t);
-
-       void *val = load_cattr_value (image, t, p, end, error);
-       if (!is_ok (error)) {
-               if (is_ref)
-                       g_free (val);
-               return NULL;
-       }
-
-       if (is_ref)
-               return (MonoObject*)val;
-
-       MonoObject *boxed = mono_value_box_checked (domain, mono_class_from_mono_type (t), val, error);
-       g_free (val);
-       return boxed;
-}
-
-static MonoObject*
-create_cattr_typed_arg (MonoType *t, MonoObject *val, MonoError *error)
-{
-       static MonoMethod *ctor;
-       MonoObject *retval;
-       void *params [2], *unboxed;
-
-       mono_error_init (error);
-
-       if (!ctor)
-               ctor = mono_class_get_method_from_name (mono_class_get_custom_attribute_typed_argument_class (), ".ctor", 2);
-       
-       params [0] = mono_type_get_object_checked (mono_domain_get (), t, error);
-       return_val_if_nok (error, NULL);
-
-       params [1] = val;
-       retval = mono_object_new_checked (mono_domain_get (), mono_class_get_custom_attribute_typed_argument_class (), error);
-       return_val_if_nok (error, NULL);
-       unboxed = mono_object_unbox (retval);
-
-       mono_runtime_invoke_checked (ctor, unboxed, params, error);
-       return_val_if_nok (error, NULL);
-
-       return retval;
-}
-
-static MonoObject*
-create_cattr_named_arg (void *minfo, MonoObject *typedarg, MonoError *error)
-{
-       static MonoMethod *ctor;
-       MonoObject *retval;
-       void *unboxed, *params [2];
-
-       mono_error_init (error);
-
-       if (!ctor)
-               ctor = mono_class_get_method_from_name (mono_class_get_custom_attribute_named_argument_class (), ".ctor", 2);
-
-       params [0] = minfo;
-       params [1] = typedarg;
-       retval = mono_object_new_checked (mono_domain_get (), mono_class_get_custom_attribute_named_argument_class (), error);
-       return_val_if_nok (error, NULL);
-
-       unboxed = mono_object_unbox (retval);
-
-       mono_runtime_invoke_checked (ctor, unboxed, params, error);
-       return_val_if_nok (error, NULL);
-
-       return retval;
-}
-
-static gboolean
-type_is_reference (MonoType *type)
-{
-       switch (type->type) {
-       case MONO_TYPE_BOOLEAN:
-       case MONO_TYPE_CHAR:
-       case MONO_TYPE_U:
-       case MONO_TYPE_I:
-       case MONO_TYPE_U1:
-       case MONO_TYPE_I1:
-       case MONO_TYPE_U2:
-       case MONO_TYPE_I2:
-       case MONO_TYPE_U4:
-       case MONO_TYPE_I4:
-       case MONO_TYPE_U8:
-       case MONO_TYPE_I8:
-       case MONO_TYPE_R8:
-       case MONO_TYPE_R4:
-       case MONO_TYPE_VALUETYPE:
-               return FALSE;
-       default:
-               return TRUE;
-       }
-}
-
-static void
-free_param_data (MonoMethodSignature *sig, void **params) {
-       int i;
-       for (i = 0; i < sig->param_count; ++i) {
-               if (!type_is_reference (sig->params [i]))
-                       g_free (params [i]);
-       }
-}
-
-/*
- * Find the field index in the metadata FieldDef table.
- */
-static guint32
-find_field_index (MonoClass *klass, MonoClassField *field) {
-       int i;
-
-       for (i = 0; i < klass->field.count; ++i) {
-               if (field == &klass->fields [i])
-                       return klass->field.first + 1 + i;
-       }
-       return 0;
-}
-
-/*
- * Find the property index in the metadata Property table.
- */
-static guint32
-find_property_index (MonoClass *klass, MonoProperty *property) {
-       int i;
-
-       for (i = 0; i < klass->ext->property.count; ++i) {
-               if (property == &klass->ext->properties [i])
-                       return klass->ext->property.first + 1 + i;
-       }
-       return 0;
-}
-
-/*
- * Find the event index in the metadata Event table.
- */
-static guint32
-find_event_index (MonoClass *klass, MonoEvent *event) {
-       int i;
-
-       for (i = 0; i < klass->ext->event.count; ++i) {
-               if (event == &klass->ext->events [i])
-                       return klass->ext->event.first + 1 + i;
-       }
-       return 0;
-}
-
-static MonoObject*
-create_custom_attr (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len, MonoError *error)
-{
-       const char *p = (const char*)data;
-       const char *named;
-       guint32 i, j, num_named;
-       MonoObject *attr;
-       void *params_buf [32];
-       void **params = NULL;
-       MonoMethodSignature *sig;
-
-       mono_error_init (error);
-
-       mono_class_init (method->klass);
-
-       if (!mono_verifier_verify_cattr_content (image, method, data, len, NULL)) {
-               mono_error_set_generic_error (error, "System.Reflection", "CustomAttributeFormatException", "Binary format of the specified custom attribute was invalid.");
-               return NULL;
-       }
-
-       if (len == 0) {
-               attr = mono_object_new_checked (mono_domain_get (), method->klass, error);
-               if (!mono_error_ok (error)) return NULL;
-
-               mono_runtime_invoke_checked (method, attr, NULL, error);
-               if (!mono_error_ok (error))
-                       return NULL;
-
-               return attr;
-       }
-
-       if (len < 2 || read16 (p) != 0x0001) /* Prolog */
-               return NULL;
-
-       /*g_print ("got attr %s\n", method->klass->name);*/
-
-       sig = mono_method_signature (method);
-       if (sig->param_count < 32) {
-               params = params_buf;
-               memset (params, 0, sizeof (void*) * sig->param_count);
-       } else {
-               /* Allocate using GC so it gets GC tracking */
-               params = (void **)mono_gc_alloc_fixed (sig->param_count * sizeof (void*), MONO_GC_DESCRIPTOR_NULL, MONO_ROOT_SOURCE_REFLECTION, "custom attribute parameters");
-       }
-
-       /* skip prolog */
-       p += 2;
-       for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
-               params [i] = load_cattr_value (image, mono_method_signature (method)->params [i], p, &p, error);
-               if (!mono_error_ok (error))
-                       goto fail;
-       }
-
-       named = p;
-       attr = mono_object_new_checked (mono_domain_get (), method->klass, error);
-       if (!mono_error_ok (error)) goto fail;
-
-       MonoObject *exc = NULL;
-       mono_runtime_try_invoke (method, attr, params, &exc, error);
-       if (!mono_error_ok (error))
-               goto fail;
-       if (exc) {
-               mono_error_set_exception_instance (error, (MonoException*)exc);
-               goto fail;
-       }
-
-       num_named = read16 (named);
-       named += 2;
-       for (j = 0; j < num_named; j++) {
-               gint name_len;
-               char *name, named_type, data_type;
-               named_type = *named++;
-               data_type = *named++; /* type of data */
-               if (data_type == MONO_TYPE_SZARRAY)
-                       data_type = *named++;
-               if (data_type == MONO_TYPE_ENUM) {
-                       gint type_len;
-                       char *type_name;
-                       type_len = mono_metadata_decode_blob_size (named, &named);
-                       type_name = (char *)g_malloc (type_len + 1);
-                       memcpy (type_name, named, type_len);
-                       type_name [type_len] = 0;
-                       named += type_len;
-                       /* FIXME: lookup the type and check type consistency */
-                       g_free (type_name);
-               }
-               name_len = mono_metadata_decode_blob_size (named, &named);
-               name = (char *)g_malloc (name_len + 1);
-               memcpy (name, named, name_len);
-               name [name_len] = 0;
-               named += name_len;
-               if (named_type == 0x53) {
-                       MonoClassField *field;
-                       void *val;
-
-                       /* how this fail is a blackbox */
-                       field = mono_class_get_field_from_name (mono_object_class (attr), name);
-                       if (!field) {
-                               mono_error_set_generic_error (error, "System.Reflection", "CustomAttributeFormatException", "Could not find a field with name %s", name);
-                               g_free (name);
-                               goto fail;
-                       }
-
-                       val = load_cattr_value (image, field->type, named, &named, error);
-                       if (!mono_error_ok (error)) {
-                               g_free (name);
-                               if (!type_is_reference (field->type))
-                                       g_free (val);
-                               goto fail;
-                       }
-
-                       mono_field_set_value (attr, field, val);
-                       if (!type_is_reference (field->type))
-                               g_free (val);
-               } else if (named_type == 0x54) {
-                       MonoProperty *prop;
-                       void *pparams [1];
-                       MonoType *prop_type;
-
-                       prop = mono_class_get_property_from_name (mono_object_class (attr), name);
-
-                       if (!prop) {
-                               mono_error_set_generic_error (error, "System.Reflection", "CustomAttributeFormatException", "Could not find a property with name %s", name);
-                               g_free (name);
-                               goto fail;
-                       }
-
-                       if (!prop->set) {
-                               mono_error_set_generic_error (error, "System.Reflection", "CustomAttributeFormatException", "Could not find the setter for %s", name);
-                               g_free (name);
-                               goto fail;
-                       }
-
-                       /* can we have more that 1 arg in a custom attr named property? */
-                       prop_type = prop->get? mono_method_signature (prop->get)->ret :
-                            mono_method_signature (prop->set)->params [mono_method_signature (prop->set)->param_count - 1];
-
-                       pparams [0] = load_cattr_value (image, prop_type, named, &named, error);
-                       if (!mono_error_ok (error)) {
-                               g_free (name);
-                               if (!type_is_reference (prop_type))
-                                       g_free (pparams [0]);
-                               goto fail;
-                       }
-
-
-                       mono_property_set_value_checked (prop, attr, pparams, error);
-                       if (!type_is_reference (prop_type))
-                               g_free (pparams [0]);
-                       if (!is_ok (error)) {
-                               g_free (name);
-                               goto fail;
-                       }
-               }
-               g_free (name);
-       }
-
-       free_param_data (method->signature, params);
-       if (params != params_buf)
-               mono_gc_free_fixed (params);
-
-       return attr;
-
-fail:
-       free_param_data (method->signature, params);
-       if (params != params_buf)
-               mono_gc_free_fixed (params);
-       return NULL;
-}
-       
-/*
- * mono_reflection_create_custom_attr_data_args:
- *
- *   Create an array of typed and named arguments from the cattr blob given by DATA.
- * TYPED_ARGS and NAMED_ARGS will contain the objects representing the arguments,
- * NAMED_ARG_INFO will contain information about the named arguments.
- */
-void
-mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len, MonoArray **typed_args, MonoArray **named_args, CattrNamedArg **named_arg_info, MonoError *error)
-{
-       MonoArray *typedargs, *namedargs;
-       MonoClass *attrklass;
-       MonoDomain *domain;
-       const char *p = (const char*)data;
-       const char *named;
-       guint32 i, j, num_named;
-       CattrNamedArg *arginfo = NULL;
-
-       *typed_args = NULL;
-       *named_args = NULL;
-       *named_arg_info = NULL;
-
-       mono_error_init (error);
-
-       if (!mono_verifier_verify_cattr_content (image, method, data, len, NULL)) {
-               mono_error_set_generic_error (error, "System.Reflection", "CustomAttributeFormatException", "Binary format of the specified custom attribute was invalid.");
-               return;
-       }
-
-       mono_class_init (method->klass);
-       
-       domain = mono_domain_get ();
-
-       if (len < 2 || read16 (p) != 0x0001) /* Prolog */
-               return;
-
-       typedargs = mono_array_new_checked (domain, mono_get_object_class (), mono_method_signature (method)->param_count, error);
-       return_if_nok (error);
-
-       /* skip prolog */
-       p += 2;
-       for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
-               MonoObject *obj;
-
-               obj = load_cattr_value_boxed (domain, image, mono_method_signature (method)->params [i], p, &p, error);
-               return_if_nok (error);
-               mono_array_setref (typedargs, i, obj);
-       }
-
-       named = p;
-       num_named = read16 (named);
-       namedargs = mono_array_new_checked (domain, mono_get_object_class (), num_named, error);
-       return_if_nok (error);
-       named += 2;
-       attrklass = method->klass;
-
-       arginfo = g_new0 (CattrNamedArg, num_named);
-       *named_arg_info = arginfo;
-
-       for (j = 0; j < num_named; j++) {
-               gint name_len;
-               char *name, named_type, data_type;
-               named_type = *named++;
-               data_type = *named++; /* type of data */
-               if (data_type == MONO_TYPE_SZARRAY)
-                       data_type = *named++;
-               if (data_type == MONO_TYPE_ENUM) {
-                       gint type_len;
-                       char *type_name;
-                       type_len = mono_metadata_decode_blob_size (named, &named);
-                       if (ADDP_IS_GREATER_OR_OVF ((const guchar*)named, type_len, data + len))
-                               goto fail;
-
-                       type_name = (char *)g_malloc (type_len + 1);
-                       memcpy (type_name, named, type_len);
-                       type_name [type_len] = 0;
-                       named += type_len;
-                       /* FIXME: lookup the type and check type consistency */
-                       g_free (type_name);
-               }
-               name_len = mono_metadata_decode_blob_size (named, &named);
-               if (ADDP_IS_GREATER_OR_OVF ((const guchar*)named, name_len, data + len))
-                       goto fail;
-               name = (char *)g_malloc (name_len + 1);
-               memcpy (name, named, name_len);
-               name [name_len] = 0;
-               named += name_len;
-               if (named_type == 0x53) {
-                       MonoObject *obj;
-                       MonoClassField *field = mono_class_get_field_from_name (attrklass, name);
-
-                       if (!field) {
-                               g_free (name);
-                               goto fail;
-                       }
-
-                       arginfo [j].type = field->type;
-                       arginfo [j].field = field;
-
-                       obj = load_cattr_value_boxed (domain, image, field->type, named, &named, error);
-                       if (!is_ok (error)) {
-                               g_free (name);
-                               return;
-                       }
-                       mono_array_setref (namedargs, j, obj);
-
-               } else if (named_type == 0x54) {
-                       MonoObject *obj;
-                       MonoType *prop_type;
-                       MonoProperty *prop = mono_class_get_property_from_name (attrklass, name);
-
-                       if (!prop || !prop->set) {
-                               g_free (name);
-                               goto fail;
-                       }
-
-                       prop_type = prop->get? mono_method_signature (prop->get)->ret :
-                            mono_method_signature (prop->set)->params [mono_method_signature (prop->set)->param_count - 1];
-
-                       arginfo [j].type = prop_type;
-                       arginfo [j].prop = prop;
-
-                       obj = load_cattr_value_boxed (domain, image, prop_type, named, &named, error);
-                       if (!is_ok (error)) {
-                               g_free (name);
-                               return;
-                       }
-                       mono_array_setref (namedargs, j, obj);
-               }
-               g_free (name);
-       }
-
-       *typed_args = typedargs;
-       *named_args = namedargs;
-       return;
-fail:
-       mono_error_set_generic_error (error, "System.Reflection", "CustomAttributeFormatException", "Binary format of the specified custom attribute was invalid.");
-       g_free (arginfo);
-       *named_arg_info = NULL;
-}
-
-static gboolean
-reflection_resolve_custom_attribute_data (MonoReflectionMethod *ref_method, MonoReflectionAssembly *assembly, gpointer data, guint32 len, MonoArray **ctor_args, MonoArray **named_args, MonoError *error)
-{
-       MonoDomain *domain;
-       MonoArray *typedargs, *namedargs;
-       MonoImage *image;
-       MonoMethod *method;
-       CattrNamedArg *arginfo = NULL;
-       int i;
-
-       mono_error_init (error);
-
-       *ctor_args = NULL;
-       *named_args = NULL;
-
-       if (len == 0)
-               return TRUE;
-
-       image = assembly->assembly->image;
-       method = ref_method->method;
-       domain = mono_object_domain (ref_method);
-
-       if (!mono_class_init (method->klass)) {
-               mono_error_set_for_class_failure (error, method->klass);
-               goto leave;
-       }
-
-       mono_reflection_create_custom_attr_data_args (image, method, (const guchar *)data, len, &typedargs, &namedargs, &arginfo, error);
-       if (!is_ok (error))
-               goto leave;
-
-       if (!typedargs || !namedargs)
-               goto leave;
-
-       for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
-               MonoObject *obj = mono_array_get (typedargs, MonoObject*, i);
-               MonoObject *typedarg;
-
-               typedarg = create_cattr_typed_arg (mono_method_signature (method)->params [i], obj, error);
-               if (!is_ok (error))
-                       goto leave;
-               mono_array_setref (typedargs, i, typedarg);
-       }
-
-       for (i = 0; i < mono_array_length (namedargs); ++i) {
-               MonoObject *obj = mono_array_get (namedargs, MonoObject*, i);
-               MonoObject *typedarg, *namedarg, *minfo;
-
-               if (arginfo [i].prop) {
-                       minfo = (MonoObject*)mono_property_get_object_checked (domain, NULL, arginfo [i].prop, error);
-                       if (!minfo)
-                               goto leave;
-               } else {
-                       minfo = (MonoObject*)mono_field_get_object_checked (domain, NULL, arginfo [i].field, error);
-                       if (!is_ok (error))
-                               goto leave;
-               }
-
-               typedarg = create_cattr_typed_arg (arginfo [i].type, obj, error);
-               if (!is_ok (error))
-                       goto leave;
-               namedarg = create_cattr_named_arg (minfo, typedarg, error);
-               if (!is_ok (error))
-                       goto leave;
-
-               mono_array_setref (namedargs, i, namedarg);
-       }
-
-       *ctor_args = typedargs;
-       *named_args = namedargs;
-
-leave:
-       g_free (arginfo);
-       return mono_error_ok (error);
-}
-
-void
-ves_icall_System_Reflection_CustomAttributeData_ResolveArgumentsInternal (MonoReflectionMethod *ref_method, MonoReflectionAssembly *assembly, gpointer data, guint32 len, MonoArray **ctor_args, MonoArray **named_args)
-{
-       MonoError error;
-       (void) reflection_resolve_custom_attribute_data (ref_method, assembly, data, len, ctor_args, named_args, &error);
-       mono_error_set_pending_exception (&error);
-}
-
-static MonoObject*
-create_custom_attr_data (MonoImage *image, MonoCustomAttrEntry *cattr, MonoError *error)
-{
-       static MonoMethod *ctor;
-
-       MonoDomain *domain;
-       MonoObject *attr;
-       void *params [4];
-
-       mono_error_init (error);
-
-       g_assert (image->assembly);
-
-       if (!ctor)
-               ctor = mono_class_get_method_from_name (mono_defaults.customattribute_data_class, ".ctor", 4);
-
-       domain = mono_domain_get ();
-       attr = mono_object_new_checked (domain, mono_defaults.customattribute_data_class, error);
-       return_val_if_nok (error, NULL);
-       params [0] = mono_method_get_object_checked (domain, cattr->ctor, NULL, error);
-       return_val_if_nok (error, NULL);
-       params [1] = mono_assembly_get_object_checked (domain, image->assembly, error);
-       return_val_if_nok (error, NULL);
-       params [2] = (gpointer)&cattr->data;
-       params [3] = &cattr->data_size;
-
-       mono_runtime_invoke_checked (ctor, attr, params, error);
-       return_val_if_nok (error, NULL);
-       return attr;
-}
-
-static MonoArray*
-mono_custom_attrs_construct_by_type (MonoCustomAttrInfo *cinfo, MonoClass *attr_klass, MonoError *error)
-{
-       MonoArray *result;
-       MonoObject *attr;
-       int i, n;
-
-       mono_error_init (error);
-
-       for (i = 0; i < cinfo->num_attrs; ++i) {
-               MonoCustomAttrEntry *centry = &cinfo->attrs[i];
-               if (!centry->ctor) {
-                       /* The cattr type is not finished yet */
-                       /* We should include the type name but cinfo doesn't contain it */
-                       mono_error_set_type_load_name (error, NULL, NULL, "Custom attribute constructor is null because the custom attribute type is not finished yet.");
-                       return NULL;
-               }
-       }
-
-       n = 0;
-       if (attr_klass) {
-               for (i = 0; i < cinfo->num_attrs; ++i) {
-                       MonoMethod *ctor = cinfo->attrs[i].ctor;
-                       g_assert (ctor);
-                       if (mono_class_is_assignable_from (attr_klass, ctor->klass))
-                               n++;
-               }
-       } else {
-               n = cinfo->num_attrs;
-       }
-
-       result = mono_array_new_cached (mono_domain_get (), mono_defaults.attribute_class, n, error);
-       return_val_if_nok (error, NULL);
-       n = 0;
-       for (i = 0; i < cinfo->num_attrs; ++i) {
-               MonoCustomAttrEntry *centry = &cinfo->attrs [i];
-               if (!attr_klass || mono_class_is_assignable_from (attr_klass, centry->ctor->klass)) {
-                       attr = create_custom_attr (cinfo->image, centry->ctor, centry->data, centry->data_size, error);
-                       if (!mono_error_ok (error))
-                               return result;
-                       mono_array_setref (result, n, attr);
-                       n ++;
-               }
-       }
-       return result;
-}
-
-MonoArray*
-mono_custom_attrs_construct (MonoCustomAttrInfo *cinfo)
-{
-       MonoError error;
-       MonoArray *result = mono_custom_attrs_construct_by_type (cinfo, NULL, &error);
-       mono_error_assert_ok (&error); /*FIXME proper error handling*/
-
-       return result;
-}
-
-static MonoArray*
-mono_custom_attrs_data_construct (MonoCustomAttrInfo *cinfo, MonoError *error)
-{
-       MonoArray *result;
-       MonoObject *attr;
-       int i;
-       
-       mono_error_init (error);
-       result = mono_array_new_checked (mono_domain_get (), mono_defaults.customattribute_data_class, cinfo->num_attrs, error);
-       return_val_if_nok (error, NULL);
-       for (i = 0; i < cinfo->num_attrs; ++i) {
-               attr = create_custom_attr_data (cinfo->image, &cinfo->attrs [i], error);
-               return_val_if_nok (error, NULL);
-               mono_array_setref (result, i, attr);
-       }
-       return result;
-}
-
-/**
- * mono_custom_attrs_from_index:
- *
- * Returns: NULL if no attributes are found or if a loading error occurs.
- */
-MonoCustomAttrInfo*
-mono_custom_attrs_from_index (MonoImage *image, guint32 idx)
-{
-       MonoError error;
-       MonoCustomAttrInfo *result = mono_custom_attrs_from_index_checked (image, idx, &error);
-       mono_error_cleanup (&error);
-       return result;
-}
-/**
- * mono_custom_attrs_from_index_checked:
- *
- * Returns: NULL if no attributes are found.  On error returns NULL and sets @error.
- */
-MonoCustomAttrInfo*
-mono_custom_attrs_from_index_checked (MonoImage *image, guint32 idx, MonoError *error)
-{
-       guint32 mtoken, i, len;
-       guint32 cols [MONO_CUSTOM_ATTR_SIZE];
-       MonoTableInfo *ca;
-       MonoCustomAttrInfo *ainfo;
-       GList *tmp, *list = NULL;
-       const char *data;
-       MonoCustomAttrEntry* attr;
-
-       mono_error_init (error);
-
-       ca = &image->tables [MONO_TABLE_CUSTOMATTRIBUTE];
-
-       i = mono_metadata_custom_attrs_from_index (image, idx);
-       if (!i)
-               return NULL;
-       i --;
-       while (i < ca->rows) {
-               if (mono_metadata_decode_row_col (ca, i, MONO_CUSTOM_ATTR_PARENT) != idx)
-                       break;
-               list = g_list_prepend (list, GUINT_TO_POINTER (i));
-               ++i;
-       }
-       len = g_list_length (list);
-       if (!len)
-               return NULL;
-       ainfo = (MonoCustomAttrInfo *)g_malloc0 (MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * len);
-       ainfo->num_attrs = len;
-       ainfo->image = image;
-       for (i = len, tmp = list; i != 0; --i, tmp = tmp->next) {
-               mono_metadata_decode_row (ca, GPOINTER_TO_UINT (tmp->data), cols, MONO_CUSTOM_ATTR_SIZE);
-               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_error ("Unknown table for custom attr type %08x", cols [MONO_CUSTOM_ATTR_TYPE]);
-                       break;
-               }
-               attr = &ainfo->attrs [i - 1];
-               attr->ctor = mono_get_method_checked (image, mtoken, NULL, NULL, error);
-               if (!attr->ctor) {
-                       g_warning ("Can't find custom attr constructor image: %s mtoken: 0x%08x due to %s", image->name, mtoken, mono_error_get_message (error));
-                       g_list_free (list);
-                       g_free (ainfo);
-                       return NULL;
-               }
-
-               if (!mono_verifier_verify_cattr_blob (image, cols [MONO_CUSTOM_ATTR_VALUE], NULL)) {
-                       /*FIXME raising an exception here doesn't make any sense*/
-                       g_warning ("Invalid custom attribute blob on image %s for index %x", image->name, idx);
-                       g_list_free (list);
-                       g_free (ainfo);
-                       return NULL;
-               }
-               data = mono_metadata_blob_heap (image, cols [MONO_CUSTOM_ATTR_VALUE]);
-               attr->data_size = mono_metadata_decode_value (data, &data);
-               attr->data = (guchar*)data;
-       }
-       g_list_free (list);
-
-       return ainfo;
-}
-
-MonoCustomAttrInfo*
-mono_custom_attrs_from_method (MonoMethod *method)
-{
-       MonoError error;
-       MonoCustomAttrInfo* result = mono_custom_attrs_from_method_checked  (method, &error);
-       mono_error_cleanup (&error); /* FIXME want a better API that doesn't swallow the error */
-       return result;
-}
-
-MonoCustomAttrInfo*
-mono_custom_attrs_from_method_checked (MonoMethod *method, MonoError *error)
-{
-       guint32 idx;
-
-       mono_error_init (error);
-
-       /*
-        * An instantiated method has the same cattrs as the generic method definition.
-        *
-        * LAMESPEC: The .NET SRE throws an exception for instantiations of generic method builders
-        *           Note that this stanza is not necessary for non-SRE types, but it's a micro-optimization
-        */
-       if (method->is_inflated)
-               method = ((MonoMethodInflated *) method)->declaring;
-       
-       if (method_is_dynamic (method) || image_is_dynamic (method->klass->image))
-               return lookup_custom_attr (method->klass->image, method);
-
-       if (!method->token)
-               /* Synthetic methods */
-               return NULL;
-
-       idx = mono_method_get_index (method);
-       idx <<= MONO_CUSTOM_ATTR_BITS;
-       idx |= MONO_CUSTOM_ATTR_METHODDEF;
-       return mono_custom_attrs_from_index_checked (method->klass->image, idx, error);
-}
-
-MonoCustomAttrInfo*
-mono_custom_attrs_from_class (MonoClass *klass)
-{
-       MonoError error;
-       MonoCustomAttrInfo *result = mono_custom_attrs_from_class_checked (klass, &error);
-       mono_error_cleanup (&error);
-       return result;
-}
-
-MonoCustomAttrInfo*
-mono_custom_attrs_from_class_checked (MonoClass *klass, MonoError *error)
-{
-       guint32 idx;
-
-       mono_error_init (error);
-
-       if (klass->generic_class)
-               klass = klass->generic_class->container_class;
-
-       if (image_is_dynamic (klass->image))
-               return lookup_custom_attr (klass->image, klass);
-
-       if (klass->byval_arg.type == MONO_TYPE_VAR || klass->byval_arg.type == MONO_TYPE_MVAR) {
-               idx = mono_metadata_token_index (klass->sizes.generic_param_token);
-               idx <<= MONO_CUSTOM_ATTR_BITS;
-               idx |= MONO_CUSTOM_ATTR_GENERICPAR;
-       } else {
-               idx = mono_metadata_token_index (klass->type_token);
-               idx <<= MONO_CUSTOM_ATTR_BITS;
-               idx |= MONO_CUSTOM_ATTR_TYPEDEF;
-       }
-       return mono_custom_attrs_from_index_checked (klass->image, idx, error);
-}
-
-MonoCustomAttrInfo*
-mono_custom_attrs_from_assembly (MonoAssembly *assembly)
-{
-       MonoError error;
-       MonoCustomAttrInfo *result = mono_custom_attrs_from_assembly_checked (assembly, &error);
-       mono_error_cleanup (&error);
-       return result;
-}
-
-MonoCustomAttrInfo*
-mono_custom_attrs_from_assembly_checked (MonoAssembly *assembly, MonoError *error)
-{
-       guint32 idx;
-       
-       mono_error_init (error);
-
-       if (image_is_dynamic (assembly->image))
-               return lookup_custom_attr (assembly->image, assembly);
-       idx = 1; /* there is only one assembly */
-       idx <<= MONO_CUSTOM_ATTR_BITS;
-       idx |= MONO_CUSTOM_ATTR_ASSEMBLY;
-       return mono_custom_attrs_from_index_checked (assembly->image, idx, error);
-}
-
-static MonoCustomAttrInfo*
-mono_custom_attrs_from_module (MonoImage *image, MonoError *error)
-{
-       guint32 idx;
-       
-       if (image_is_dynamic (image))
-               return lookup_custom_attr (image, image);
-       idx = 1; /* there is only one module */
-       idx <<= MONO_CUSTOM_ATTR_BITS;
-       idx |= MONO_CUSTOM_ATTR_MODULE;
-       return mono_custom_attrs_from_index_checked (image, idx, error);
-}
-
-MonoCustomAttrInfo*
-mono_custom_attrs_from_property (MonoClass *klass, MonoProperty *property)
-{
-       MonoError error;
-       MonoCustomAttrInfo * result = mono_custom_attrs_from_property_checked (klass, property, &error);
-       mono_error_cleanup (&error);
-       return result;
-}
-
-MonoCustomAttrInfo*
-mono_custom_attrs_from_property_checked (MonoClass *klass, MonoProperty *property, MonoError *error)
-{
-       guint32 idx;
-       
-       if (image_is_dynamic (klass->image)) {
-               property = mono_metadata_get_corresponding_property_from_generic_type_definition (property);
-               return lookup_custom_attr (klass->image, property);
-       }
-       idx = find_property_index (klass, property);
-       idx <<= MONO_CUSTOM_ATTR_BITS;
-       idx |= MONO_CUSTOM_ATTR_PROPERTY;
-       return mono_custom_attrs_from_index_checked (klass->image, idx, error);
-}
-
-MonoCustomAttrInfo*
-mono_custom_attrs_from_event (MonoClass *klass, MonoEvent *event)
-{
-       MonoError error;
-       MonoCustomAttrInfo * result = mono_custom_attrs_from_event_checked (klass, event, &error);
-       mono_error_cleanup (&error);
-       return result;
-}
-
-MonoCustomAttrInfo*
-mono_custom_attrs_from_event_checked (MonoClass *klass, MonoEvent *event, MonoError *error)
-{
-       guint32 idx;
-       
-       if (image_is_dynamic (klass->image)) {
-               event = mono_metadata_get_corresponding_event_from_generic_type_definition (event);
-               return lookup_custom_attr (klass->image, event);
-       }
-       idx = find_event_index (klass, event);
-       idx <<= MONO_CUSTOM_ATTR_BITS;
-       idx |= MONO_CUSTOM_ATTR_EVENT;
-       return mono_custom_attrs_from_index_checked (klass->image, idx, error);
-}
-
-MonoCustomAttrInfo*
-mono_custom_attrs_from_field (MonoClass *klass, MonoClassField *field)
-{
-       MonoError error;
-       MonoCustomAttrInfo * result = mono_custom_attrs_from_field_checked (klass, field, &error);
-       mono_error_cleanup (&error);
-       return result;
-}
-
-MonoCustomAttrInfo*
-mono_custom_attrs_from_field_checked (MonoClass *klass, MonoClassField *field, MonoError *error)
-{
-       guint32 idx;
-       mono_error_init (error);
-
-       if (image_is_dynamic (klass->image)) {
-               field = mono_metadata_get_corresponding_field_from_generic_type_definition (field);
-               return lookup_custom_attr (klass->image, field);
-       }
-       idx = find_field_index (klass, field);
-       idx <<= MONO_CUSTOM_ATTR_BITS;
-       idx |= MONO_CUSTOM_ATTR_FIELDDEF;
-       return mono_custom_attrs_from_index_checked (klass->image, idx, error);
-}
-
-/**
- * mono_custom_attrs_from_param:
- * @method: handle to the method that we want to retrieve custom parameter information from
- * @param: parameter number, where zero represent the return value, and one is the first parameter in the method
- *
- * The result must be released with mono_custom_attrs_free().
- *
- * Returns: the custom attribute object for the specified parameter, or NULL if there are none.
- */
-MonoCustomAttrInfo*
-mono_custom_attrs_from_param (MonoMethod *method, guint32 param)
-{
-       MonoError error;
-       MonoCustomAttrInfo *result = mono_custom_attrs_from_param_checked (method, param, &error);
-       mono_error_cleanup (&error);
-       return result;
-}
-
-/**
- * mono_custom_attrs_from_param_checked:
- * @method: handle to the method that we want to retrieve custom parameter information from
- * @param: parameter number, where zero represent the return value, and one is the first parameter in the method
- * @error: set on error
- *
- * The result must be released with mono_custom_attrs_free().
- *
- * Returns: the custom attribute object for the specified parameter, or NULL if there are none.  On failure returns NULL and sets @error.
- */
-MonoCustomAttrInfo*
-mono_custom_attrs_from_param_checked (MonoMethod *method, guint32 param, MonoError *error)
-{
-       MonoTableInfo *ca;
-       guint32 i, idx, method_index;
-       guint32 param_list, param_last, param_pos, found;
-       MonoImage *image;
-       MonoReflectionMethodAux *aux;
-
-       mono_error_init (error);
-
-       /*
-        * An instantiated method has the same cattrs as the generic method definition.
-        *
-        * LAMESPEC: The .NET SRE throws an exception for instantiations of generic method builders
-        *           Note that this stanza is not necessary for non-SRE types, but it's a micro-optimization
-        */
-       if (method->is_inflated)
-               method = ((MonoMethodInflated *) method)->declaring;
-
-       if (image_is_dynamic (method->klass->image)) {
-               MonoCustomAttrInfo *res, *ainfo;
-               int size;
-
-               aux = (MonoReflectionMethodAux *)g_hash_table_lookup (((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
-               if (!aux || !aux->param_cattr)
-                       return NULL;
-
-               /* Need to copy since it will be freed later */
-               ainfo = aux->param_cattr [param];
-               if (!ainfo)
-                       return NULL;
-               size = MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * ainfo->num_attrs;
-               res = (MonoCustomAttrInfo *)g_malloc0 (size);
-               memcpy (res, ainfo, size);
-               return res;
-       }
-
-       image = method->klass->image;
-       method_index = mono_method_get_index (method);
-       if (!method_index)
-               return NULL;
-       ca = &image->tables [MONO_TABLE_METHOD];
-
-       param_list = mono_metadata_decode_row_col (ca, method_index - 1, MONO_METHOD_PARAMLIST);
-       if (method_index == ca->rows) {
-               ca = &image->tables [MONO_TABLE_PARAM];
-               param_last = ca->rows + 1;
-       } else {
-               param_last = mono_metadata_decode_row_col (ca, method_index, MONO_METHOD_PARAMLIST);
-               ca = &image->tables [MONO_TABLE_PARAM];
-       }
-       found = FALSE;
-       for (i = param_list; i < param_last; ++i) {
-               param_pos = mono_metadata_decode_row_col (ca, i - 1, MONO_PARAM_SEQUENCE);
-               if (param_pos == param) {
-                       found = TRUE;
-                       break;
-               }
-       }
-       if (!found)
-               return NULL;
-       idx = i;
-       idx <<= MONO_CUSTOM_ATTR_BITS;
-       idx |= MONO_CUSTOM_ATTR_PARAMDEF;
-       return mono_custom_attrs_from_index_checked (image, idx, error);
-}
-
-gboolean
-mono_custom_attrs_has_attr (MonoCustomAttrInfo *ainfo, MonoClass *attr_klass)
-{
-       int i;
-       for (i = 0; i < ainfo->num_attrs; ++i) {
-               MonoClass *klass = ainfo->attrs [i].ctor->klass;
-               if (mono_class_has_parent (klass, attr_klass) || (MONO_CLASS_IS_INTERFACE (attr_klass) && mono_class_is_assignable_from (attr_klass, klass)))
-                       return TRUE;
-       }
-       return FALSE;
-}
-
-MonoObject*
-mono_custom_attrs_get_attr (MonoCustomAttrInfo *ainfo, MonoClass *attr_klass)
-{
-       MonoError error;
-       MonoObject *res = mono_custom_attrs_get_attr_checked (ainfo, attr_klass, &error);
-       mono_error_assert_ok (&error); /*FIXME proper error handling*/
-       return res;
-}
-
-MonoObject*
-mono_custom_attrs_get_attr_checked (MonoCustomAttrInfo *ainfo, MonoClass *attr_klass, MonoError *error)
-{
-       int i, attr_index;
-       MonoArray *attrs;
-
-       mono_error_init (error);
-
-       attr_index = -1;
-       for (i = 0; i < ainfo->num_attrs; ++i) {
-               MonoClass *klass = ainfo->attrs [i].ctor->klass;
-               if (mono_class_has_parent (klass, attr_klass)) {
-                       attr_index = i;
-                       break;
-               }
-       }
-       if (attr_index == -1)
-               return NULL;
-
-       attrs = mono_custom_attrs_construct_by_type (ainfo, NULL, error);
-       if (!mono_error_ok (error))
-               return NULL;
-       return mono_array_get (attrs, MonoObject*, attr_index);
-}
-
-/*
- * mono_reflection_get_custom_attrs_info:
- * @obj: a reflection object handle
- *
- * Return the custom attribute info for attributes defined for the
- * reflection handle @obj. The objects.
- *
- * FIXME this function leaks like a sieve for SRE objects.
- */
-MonoCustomAttrInfo*
-mono_reflection_get_custom_attrs_info (MonoObject *obj)
-{
-       MonoError error;
-       MonoCustomAttrInfo *result = mono_reflection_get_custom_attrs_info_checked (obj, &error);
-       mono_error_assert_ok (&error);
-       return result;
-}
-
-/**
- * mono_reflection_get_custom_attrs_info_checked:
- * @obj: a reflection object handle
- * @error: set on error
- *
- * Return the custom attribute info for attributes defined for the
- * reflection handle @obj. The objects.
- *
- * On failure returns NULL and sets @error.
- *
- * FIXME this function leaks like a sieve for SRE objects.
- */
-MonoCustomAttrInfo*
-mono_reflection_get_custom_attrs_info_checked (MonoObject *obj, MonoError *error)
-{
-       MonoClass *klass;
-       MonoCustomAttrInfo *cinfo = NULL;
-       
-       mono_error_init (error);
-
-       klass = obj->vtable->klass;
-       if (klass == mono_defaults.runtimetype_class) {
-               MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
-               return_val_if_nok (error, NULL);
-               klass = mono_class_from_mono_type (type);
-               /*We cannot mono_class_init the class from which we'll load the custom attributes since this must work with broken types.*/
-               cinfo = mono_custom_attrs_from_class_checked (klass, error);
-               return_val_if_nok (error, NULL);
-       } else if (strcmp ("Assembly", klass->name) == 0 || strcmp ("MonoAssembly", klass->name) == 0) {
-               MonoReflectionAssembly *rassembly = (MonoReflectionAssembly*)obj;
-               cinfo = mono_custom_attrs_from_assembly_checked (rassembly->assembly, error);
-               return_val_if_nok (error, NULL);
-       } else if (strcmp ("Module", klass->name) == 0 || strcmp ("MonoModule", klass->name) == 0) {
-               MonoReflectionModule *module = (MonoReflectionModule*)obj;
-               cinfo = mono_custom_attrs_from_module (module->image, error);
-               return_val_if_nok (error, NULL);
-       } else if (strcmp ("MonoProperty", klass->name) == 0) {
-               MonoReflectionProperty *rprop = (MonoReflectionProperty*)obj;
-               cinfo = mono_custom_attrs_from_property_checked (rprop->property->parent, rprop->property, error);
-               return_val_if_nok (error, NULL);
-       } else if (strcmp ("MonoEvent", klass->name) == 0) {
-               MonoReflectionMonoEvent *revent = (MonoReflectionMonoEvent*)obj;
-               cinfo = mono_custom_attrs_from_event_checked (revent->event->parent, revent->event, error);
-               return_val_if_nok (error, NULL);
-       } else if (strcmp ("MonoField", klass->name) == 0) {
-               MonoReflectionField *rfield = (MonoReflectionField*)obj;
-               cinfo = mono_custom_attrs_from_field_checked (rfield->field->parent, rfield->field, error);
-               return_val_if_nok (error, NULL);
-       } else if ((strcmp ("MonoMethod", klass->name) == 0) || (strcmp ("MonoCMethod", klass->name) == 0)) {
-               MonoReflectionMethod *rmethod = (MonoReflectionMethod*)obj;
-               cinfo = mono_custom_attrs_from_method_checked (rmethod->method, error);
-               return_val_if_nok (error, NULL);
-       } else if ((strcmp ("MonoGenericMethod", klass->name) == 0) || (strcmp ("MonoGenericCMethod", klass->name) == 0)) {
-               MonoReflectionMethod *rmethod = (MonoReflectionMethod*)obj;
-               cinfo = mono_custom_attrs_from_method_checked (rmethod->method, error);
-               return_val_if_nok (error, NULL);
-       } else if (strcmp ("ParameterInfo", klass->name) == 0 || strcmp ("MonoParameterInfo", klass->name) == 0) {
-               MonoReflectionParameter *param = (MonoReflectionParameter*)obj;
-               MonoClass *member_class = mono_object_class (param->MemberImpl);
-               if (mono_class_is_reflection_method_or_constructor (member_class)) {
-                       MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
-                       cinfo = mono_custom_attrs_from_param_checked (rmethod->method, param->PositionImpl + 1, error);
-                       return_val_if_nok (error, NULL);
-               } else if (is_sr_mono_property (member_class)) {
-                       MonoReflectionProperty *prop = (MonoReflectionProperty *)param->MemberImpl;
-                       MonoMethod *method;
-                       if (!(method = prop->property->get))
-                               method = prop->property->set;
-                       g_assert (method);
-
-                       cinfo = mono_custom_attrs_from_param_checked (method, param->PositionImpl + 1, error);
-                       return_val_if_nok (error, NULL);
-               } 
-#ifndef DISABLE_REFLECTION_EMIT
-               else if (is_sre_method_on_tb_inst (member_class)) {/*XXX This is a workaround for Compiler Context*/
-                       MonoMethod *method = mono_reflection_method_on_tb_inst_get_handle ((MonoReflectionMethodOnTypeBuilderInst*)param->MemberImpl, error);
-                       return_val_if_nok (error, NULL);
-                       cinfo = mono_custom_attrs_from_param_checked (method, param->PositionImpl + 1, error);
-                       return_val_if_nok (error, NULL);
-               } else if (is_sre_ctor_on_tb_inst (member_class)) { /*XX This is a workaround for Compiler Context*/
-                       MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)param->MemberImpl;
-                       MonoMethod *method = NULL;
-                       if (is_sre_ctor_builder (mono_object_class (c->cb)))
-                               method = ((MonoReflectionCtorBuilder *)c->cb)->mhandle;
-                       else if (is_sr_mono_cmethod (mono_object_class (c->cb)))
-                               method = ((MonoReflectionMethod *)c->cb)->method;
-                       else
-                               g_error ("mono_reflection_get_custom_attrs_info:: can't handle a CTBI with base_method of type %s", mono_type_get_full_name (member_class));
-
-                       cinfo = mono_custom_attrs_from_param_checked (method, param->PositionImpl + 1, error);
-                       return_val_if_nok (error, NULL);
-               } 
-#endif
-               else {
-                       char *type_name = mono_type_get_full_name (member_class);
-                       mono_error_set_not_supported (error,
-                                                     "Custom attributes on a ParamInfo with member %s are not supported",
-                                                     type_name);
-                       g_free (type_name);
-                       return NULL;
-               }
-       } else if (strcmp ("AssemblyBuilder", klass->name) == 0) {
-               MonoReflectionAssemblyBuilder *assemblyb = (MonoReflectionAssemblyBuilder*)obj;
-               cinfo = mono_custom_attrs_from_builders (NULL, assemblyb->assembly.assembly->image, assemblyb->cattrs);
-       } else if (strcmp ("TypeBuilder", klass->name) == 0) {
-               MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
-               cinfo = mono_custom_attrs_from_builders (NULL, &tb->module->dynamic_image->image, tb->cattrs);
-       } else if (strcmp ("ModuleBuilder", klass->name) == 0) {
-               MonoReflectionModuleBuilder *mb = (MonoReflectionModuleBuilder*)obj;
-               cinfo = mono_custom_attrs_from_builders (NULL, &mb->dynamic_image->image, mb->cattrs);
-       } else if (strcmp ("ConstructorBuilder", klass->name) == 0) {
-               MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder*)obj;
-               cinfo = mono_custom_attrs_from_builders (NULL, cb->mhandle->klass->image, cb->cattrs);
-       } else if (strcmp ("MethodBuilder", klass->name) == 0) {
-               MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)obj;
-               cinfo = mono_custom_attrs_from_builders (NULL, mb->mhandle->klass->image, mb->cattrs);
-       } else if (strcmp ("FieldBuilder", klass->name) == 0) {
-               MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder*)obj;
-               cinfo = mono_custom_attrs_from_builders (NULL, &((MonoReflectionTypeBuilder*)fb->typeb)->module->dynamic_image->image, fb->cattrs);
-       } else if (strcmp ("MonoGenericClass", klass->name) == 0) {
-               MonoReflectionGenericClass *gclass = (MonoReflectionGenericClass*)obj;
-               cinfo = mono_reflection_get_custom_attrs_info_checked ((MonoObject*)gclass->generic_type, error);
-               return_val_if_nok (error, NULL);
-       } else { /* handle other types here... */
-               g_error ("get custom attrs not yet supported for %s", klass->name);
-       }
-
-       return cinfo;
-}
-
-/*
- * mono_reflection_get_custom_attrs_by_type:
- * @obj: a reflection object handle
- *
- * Return an array with all the custom attributes defined of the
- * reflection handle @obj. If @attr_klass is non-NULL, only custom attributes 
- * of that type are returned. The objects are fully build. Return NULL if a loading error
- * occurs.
- */
-MonoArray*
-mono_reflection_get_custom_attrs_by_type (MonoObject *obj, MonoClass *attr_klass, MonoError *error)
-{
-       MonoArray *result;
-       MonoCustomAttrInfo *cinfo;
-
-       mono_error_init (error);
-
-       cinfo = mono_reflection_get_custom_attrs_info_checked (obj, error);
-       return_val_if_nok (error, NULL);
-       if (cinfo) {
-               result = mono_custom_attrs_construct_by_type (cinfo, attr_klass, error);
-               if (!cinfo->cached)
-                       mono_custom_attrs_free (cinfo);
-               if (!result)
-                       return NULL;
-       } else {
-               result = mono_array_new_cached (mono_domain_get (), mono_defaults.attribute_class, 0, error);
-       }
-
-       return result;
-}
-
-/*
- * mono_reflection_get_custom_attrs:
- * @obj: a reflection object handle
- *
- * Return an array with all the custom attributes defined of the
- * reflection handle @obj. The objects are fully build. Return NULL if a loading error
- * occurs.
- */
-MonoArray*
-mono_reflection_get_custom_attrs (MonoObject *obj)
-{
-       MonoError error;
-
-       return mono_reflection_get_custom_attrs_by_type (obj, NULL, &error);
-}
-
-/*
- * mono_reflection_get_custom_attrs_data:
- * @obj: a reflection obj handle
- *
- * Returns an array of System.Reflection.CustomAttributeData,
- * which include information about attributes reflected on
- * types loaded using the Reflection Only methods
- */
-MonoArray*
-mono_reflection_get_custom_attrs_data (MonoObject *obj)
-{
-       MonoError error;
-       MonoArray* result;
-       result = mono_reflection_get_custom_attrs_data_checked (obj, &error);
-       mono_error_cleanup (&error);
-       return result;
-}
-
-/*
- * mono_reflection_get_custom_attrs_data_checked:
- * @obj: a reflection obj handle
- * @error: set on error
- *
- * Returns an array of System.Reflection.CustomAttributeData,
- * which include information about attributes reflected on
- * types loaded using the Reflection Only methods
- */
-MonoArray*
-mono_reflection_get_custom_attrs_data_checked (MonoObject *obj, MonoError *error)
-{
-       MonoArray *result;
-       MonoCustomAttrInfo *cinfo;
-
-       mono_error_init (error);
-
-       cinfo = mono_reflection_get_custom_attrs_info_checked (obj, error);
-       return_val_if_nok (error, NULL);
-       if (cinfo) {
-               result = mono_custom_attrs_data_construct (cinfo, error);
-               if (!cinfo->cached)
-                       mono_custom_attrs_free (cinfo);
-               return_val_if_nok (error, NULL);
-       } else 
-               result = mono_array_new_checked (mono_domain_get (), mono_defaults.customattribute_data_class, 0, error);
-
-       return result;
-}
-
-static MonoReflectionType*
-mono_reflection_type_get_underlying_system_type (MonoReflectionType* t, MonoError *error)
-{
-       static MonoMethod *method_get_underlying_system_type = NULL;
-       MonoReflectionType *rt;
-       MonoMethod *usertype_method;
-
-       mono_error_init (error);
-
-       if (!method_get_underlying_system_type)
-               method_get_underlying_system_type = mono_class_get_method_from_name (mono_defaults.systemtype_class, "get_UnderlyingSystemType", 0);
-
-       usertype_method = mono_object_get_virtual_method ((MonoObject *) t, method_get_underlying_system_type);
-
-       rt = (MonoReflectionType *) mono_runtime_invoke_checked (usertype_method, t, NULL, error);
-
-       return rt;
-}
-
-
-static gboolean
-is_corlib_type (MonoClass *klass)
-{
-       return klass->image == mono_defaults.corlib;
-}
-
-#define check_corlib_type_cached(_class, _namespace, _name) do { \
-       static MonoClass *cached_class; \
-       if (cached_class) \
-               return cached_class == _class; \
-       if (is_corlib_type (_class) && !strcmp (_name, _class->name) && !strcmp (_namespace, _class->name_space)) { \
-               cached_class = _class; \
-               return TRUE; \
-       } \
-       return FALSE; \
-} while (0) \
-
-
-#ifndef DISABLE_REFLECTION_EMIT
-static gboolean
-is_sre_array (MonoClass *klass)
-{
-       check_corlib_type_cached (klass, "System.Reflection.Emit", "ArrayType");
-}
-
-static gboolean
-is_sre_byref (MonoClass *klass)
-{
-       check_corlib_type_cached (klass, "System.Reflection.Emit", "ByRefType");
-}
-
-static gboolean
-is_sre_pointer (MonoClass *klass)
-{
-       check_corlib_type_cached (klass, "System.Reflection.Emit", "PointerType");
-}
-
-static gboolean
-is_sre_generic_instance (MonoClass *klass)
-{
-       check_corlib_type_cached (klass, "System.Reflection", "MonoGenericClass");
-}
-
-static gboolean
-is_sre_type_builder (MonoClass *klass)
-{
-       check_corlib_type_cached (klass, "System.Reflection.Emit", "TypeBuilder");
-}
-
-static gboolean
-is_sre_method_builder (MonoClass *klass)
-{
-       check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodBuilder");
-}
-
-static gboolean
-is_sre_ctor_builder (MonoClass *klass)
-{
-       check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorBuilder");
-}
-
-static gboolean
-is_sre_field_builder (MonoClass *klass)
-{
-       check_corlib_type_cached (klass, "System.Reflection.Emit", "FieldBuilder");
-}
-
-static gboolean
-is_sre_method_on_tb_inst (MonoClass *klass)
-{
-       check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodOnTypeBuilderInst");
-}
-
-static gboolean
-is_sre_ctor_on_tb_inst (MonoClass *klass)
-{
-       check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorOnTypeBuilderInst");
-}
-
-MonoType*
-mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
-{
-       MonoClass *klass;
-       mono_error_init (error);
-
-       if (!ref)
-               return NULL;
-       if (ref->type)
-               return ref->type;
-
-       if (is_usertype (ref)) {
-               ref = mono_reflection_type_get_underlying_system_type (ref, error);
-               if (ref == NULL || is_usertype (ref) || !is_ok (error))
-                       return NULL;
-               if (ref->type)
-                       return ref->type;
-       }
-
-       klass = mono_object_class (ref);
-
-       if (is_sre_array (klass)) {
-               MonoType *res;
-               MonoReflectionArrayType *sre_array = (MonoReflectionArrayType*)ref;
-               MonoType *base = mono_reflection_type_get_handle (sre_array->element_type, error);
-               return_val_if_nok (error, NULL);
-               g_assert (base);
-               if (sre_array->rank == 0) //single dimentional array
-                       res = &mono_array_class_get (mono_class_from_mono_type (base), 1)->byval_arg;
-               else
-                       res = &mono_bounded_array_class_get (mono_class_from_mono_type (base), sre_array->rank, TRUE)->byval_arg;
-               sre_array->type.type = res;
-               return res;
-       } else if (is_sre_byref (klass)) {
-               MonoType *res;
-               MonoReflectionDerivedType *sre_byref = (MonoReflectionDerivedType*)ref;
-               MonoType *base = mono_reflection_type_get_handle (sre_byref->element_type, error);
-               return_val_if_nok (error, NULL);
-               g_assert (base);
-               res = &mono_class_from_mono_type (base)->this_arg;
-               sre_byref->type.type = res;
-               return res;
-       } else if (is_sre_pointer (klass)) {
-               MonoType *res;
-               MonoReflectionDerivedType *sre_pointer = (MonoReflectionDerivedType*)ref;
-               MonoType *base = mono_reflection_type_get_handle (sre_pointer->element_type, error);
-               return_val_if_nok (error, NULL);
-               g_assert (base);
-               res = &mono_ptr_class_get (base)->byval_arg;
-               sre_pointer->type.type = res;
-               return res;
-       } else if (is_sre_generic_instance (klass)) {
-               MonoType *res, **types;
-               MonoReflectionGenericClass *gclass = (MonoReflectionGenericClass*)ref;
-               int i, count;
-
-               count = mono_array_length (gclass->type_arguments);
-               types = g_new0 (MonoType*, count);
-               for (i = 0; i < count; ++i) {
-                       MonoReflectionType *t = (MonoReflectionType *)mono_array_get (gclass->type_arguments, gpointer, i);
-                       types [i] = mono_reflection_type_get_handle (t, error);
-                       if (!types[i] || !is_ok (error)) {
-                               g_free (types);
-                               return NULL;
-                       }
-               }
-
-               res = mono_reflection_bind_generic_parameters (gclass->generic_type, count, types, error);
-               g_free (types);
-               g_assert (res);
-               gclass->type.type = res;
-               return res;
-       }
-
-       g_error ("Cannot handle corlib user type %s", mono_type_full_name (&mono_object_class(ref)->byval_arg));
-       return NULL;
-}
-
-void
-ves_icall_SymbolType_create_unmanaged_type (MonoReflectionType *type)
-{
-       MonoError error;
-       mono_reflection_type_get_handle (type, &error);
-       mono_error_set_pending_exception (&error);
-}
-
-static gboolean
-reflection_register_with_runtime (MonoReflectionType *type, MonoError *error)
-{
-       MonoDomain *domain = mono_object_domain ((MonoObject*)type);
-       MonoClass *klass;
-
-       mono_error_init (error);
-
-       MonoType *res = mono_reflection_type_get_handle (type, error);
-
-       if (!res && is_ok (error)) {
-               mono_error_set_argument (error, NULL, "Invalid generic instantiation, one or more arguments are not proper user types");
-       }
-       return_val_if_nok (error, FALSE);
-
-       klass = mono_class_from_mono_type (res);
-
-       mono_loader_lock (); /*same locking as mono_type_get_object_checked */
-       mono_domain_lock (domain);
-
-       if (!image_is_dynamic (klass->image)) {
-               mono_class_setup_supertypes (klass);
-       } else {
-               if (!domain->type_hash)
-                       domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mono_metadata_type_hash, 
-                                       (GCompareFunc)mono_metadata_type_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection types table");
-               mono_g_hash_table_insert (domain->type_hash, res, type);
-       }
-       mono_domain_unlock (domain);
-       mono_loader_unlock ();
-
-       return TRUE;
-}
-
-void
-mono_reflection_register_with_runtime (MonoReflectionType *type)
-{
-       MonoError error;
-       (void) reflection_register_with_runtime (type, &error);
-       mono_error_set_pending_exception (&error);
-}
-
-/**
- * LOCKING: Assumes the loader lock is held.
- */
-static MonoMethodSignature*
-parameters_to_signature (MonoImage *image, MonoArray *parameters, MonoError *error) {
-       MonoMethodSignature *sig;
-       int count, i;
-
-       mono_error_init (error);
-
-       count = parameters? mono_array_length (parameters): 0;
-
-       sig = (MonoMethodSignature *)image_g_malloc0 (image, MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * count);
-       sig->param_count = count;
-       sig->sentinelpos = -1; /* FIXME */
-       for (i = 0; i < count; ++i) {
-               sig->params [i] = mono_type_array_get_and_resolve (parameters, i, error);
-               if (!is_ok (error)) {
-                       image_g_free (image, sig);
-                       return NULL;
-               }
-       }
-       return sig;
-}
-
-/**
- * LOCKING: Assumes the loader lock is held.
- */
-static MonoMethodSignature*
-ctor_builder_to_signature (MonoImage *image, MonoReflectionCtorBuilder *ctor, MonoError *error) {
-       MonoMethodSignature *sig;
-
-       mono_error_init (error);
-
-       sig = parameters_to_signature (image, ctor->parameters, error);
-       return_val_if_nok (error, NULL);
-       sig->hasthis = ctor->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
-       sig->ret = &mono_defaults.void_class->byval_arg;
-       return sig;
-}
-
-/**
- * LOCKING: Assumes the loader lock is held.
- */
-static MonoMethodSignature*
-method_builder_to_signature (MonoImage *image, MonoReflectionMethodBuilder *method, MonoError *error) {
-       MonoMethodSignature *sig;
-
-       mono_error_init (error);
-
-       sig = parameters_to_signature (image, method->parameters, error);
-       return_val_if_nok (error, NULL);
-       sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
-       if (method->rtype) {
-               sig->ret = mono_reflection_type_get_handle ((MonoReflectionType*)method->rtype, error);
-               if (!is_ok (error)) {
-                       image_g_free (image, sig);
-                       return NULL;
-               }
-       } else {
-               sig->ret = &mono_defaults.void_class->byval_arg;
-       }
-       sig->generic_param_count = method->generic_params ? mono_array_length (method->generic_params) : 0;
-       return sig;
-}
-
-static MonoMethodSignature*
-dynamic_method_to_signature (MonoReflectionDynamicMethod *method, MonoError *error) {
-       MonoMethodSignature *sig;
-
-       mono_error_init (error);
-
-       sig = parameters_to_signature (NULL, method->parameters, error);
-       return_val_if_nok (error, NULL);
-       sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
-       if (method->rtype) {
-               sig->ret = mono_reflection_type_get_handle (method->rtype, error);
-               if (!is_ok (error)) {
-                       g_free (sig);
-                       return NULL;
-               }
-       } else {
-               sig->ret = &mono_defaults.void_class->byval_arg;
-       }
-       sig->generic_param_count = 0;
-       return sig;
-}
-
-static void
-get_prop_name_and_type (MonoObject *prop, char **name, MonoType **type, MonoError *error)
-{
-       mono_error_init (error);
-       MonoClass *klass = mono_object_class (prop);
-       if (strcmp (klass->name, "PropertyBuilder") == 0) {
-               MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *)prop;
-               *name = mono_string_to_utf8_checked (pb->name, error);
-               return_if_nok (error);
-               *type = mono_reflection_type_get_handle ((MonoReflectionType*)pb->type, error);
-       } else {
-               MonoReflectionProperty *p = (MonoReflectionProperty *)prop;
-               *name = g_strdup (p->property->name);
-               if (p->property->get)
-                       *type = mono_method_signature (p->property->get)->ret;
-               else
-                       *type = mono_method_signature (p->property->set)->params [mono_method_signature (p->property->set)->param_count - 1];
-       }
-}
-
-static void
-get_field_name_and_type (MonoObject *field, char **name, MonoType **type, MonoError *error)
-{
-       mono_error_init (error);
-       MonoClass *klass = mono_object_class (field);
-       if (strcmp (klass->name, "FieldBuilder") == 0) {
-               MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)field;
-               *name = mono_string_to_utf8_checked (fb->name, error);
-               return_if_nok (error);
-               *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
-       } else {
-               MonoReflectionField *f = (MonoReflectionField *)field;
-               *name = g_strdup (mono_field_get_name (f->field));
-               *type = f->field->type;
-       }
-}
-
-#else /* DISABLE_REFLECTION_EMIT */
-
-void
-mono_reflection_register_with_runtime (MonoReflectionType *type)
-{
-       /* This is empty */
-}
-
-static gboolean
-is_sre_type_builder (MonoClass *klass)
-{
-       return FALSE;
-}
-
-static gboolean
-is_sre_generic_instance (MonoClass *klass)
-{
-       return FALSE;
-}
-
-static void
-init_type_builder_generics (MonoObject *type, MonoError *error)
-{
-       mono_error_init (error);
-}
-
-#endif /* !DISABLE_REFLECTION_EMIT */
-
-
-static gboolean
-is_sr_mono_field (MonoClass *klass)
-{
-       check_corlib_type_cached (klass, "System.Reflection", "MonoField");
-}
-
-static gboolean
-is_sr_mono_property (MonoClass *klass)
-{
-       check_corlib_type_cached (klass, "System.Reflection", "MonoProperty");
-}
-
-static gboolean
-is_sr_mono_method (MonoClass *klass)
-{
-       check_corlib_type_cached (klass, "System.Reflection", "MonoMethod");
-}
-
-static gboolean
-is_sr_mono_cmethod (MonoClass *klass)
-{
-       check_corlib_type_cached (klass, "System.Reflection", "MonoCMethod");
-}
-
-static gboolean
-is_sr_mono_generic_method (MonoClass *klass)
-{
-       check_corlib_type_cached (klass, "System.Reflection", "MonoGenericMethod");
-}
-
-static gboolean
-is_sr_mono_generic_cmethod (MonoClass *klass)
-{
-       check_corlib_type_cached (klass, "System.Reflection", "MonoGenericCMethod");
-}
-
-gboolean
-mono_class_is_reflection_method_or_constructor (MonoClass *klass)
-{
-       return is_sr_mono_method (klass) || is_sr_mono_cmethod (klass) || is_sr_mono_generic_method (klass) || is_sr_mono_generic_cmethod (klass);
-}
-
-static gboolean
-is_usertype (MonoReflectionType *ref)
-{
-       MonoClass *klass = mono_object_class (ref);
-       return klass->image != mono_defaults.corlib || strcmp ("TypeDelegator", klass->name) == 0;
-}
-
-static inline MonoBoolean
-is_generic_parameter (MonoType *type)
-{
-       return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
-}
-
-static MonoReflectionType*
-mono_reflection_type_resolve_user_types (MonoReflectionType *type, MonoError *error)
-{
-       mono_error_init (error);
-       if (!type || type->type)
-               return type;
-
-       if (is_usertype (type)) {
-               type = mono_reflection_type_get_underlying_system_type (type, error);
-               return_val_if_nok (error, NULL);
-               if (is_usertype (type)) {
-                       mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported22");
-                       return NULL;
-               }
-       }
-
-       return type;
-}
-/**
- * encode_cattr_value:
- * Encode a value in a custom attribute stream of bytes.
- * The value to encode is either supplied as an object in argument val
- * (valuetypes are boxed), or as a pointer to the data in the
- * argument argval.
- * @type represents the type of the value
- * @buffer is the start of the buffer
- * @p the current position in the buffer
- * @buflen contains the size of the buffer and is used to return the new buffer size
- * if this needs to be realloced.
- * @retbuffer and @retp return the start and the position of the buffer
- * @error set on error.
- */
-static void
-encode_cattr_value (MonoAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg, char *argval, MonoError *error)
-{
-       MonoTypeEnum simple_type;
-       
-       mono_error_init (error);
-       if ((p-buffer) + 10 >= *buflen) {
-               char *newbuf;
-               *buflen *= 2;
-               newbuf = (char *)g_realloc (buffer, *buflen);
-               p = newbuf + (p-buffer);
-               buffer = newbuf;
-       }
-       if (!argval)
-               argval = ((char*)arg + sizeof (MonoObject));
-       simple_type = type->type;
-handle_enum:
-       switch (simple_type) {
-       case MONO_TYPE_BOOLEAN:
-       case MONO_TYPE_U1:
-       case MONO_TYPE_I1:
-               *p++ = *argval;
-               break;
-       case MONO_TYPE_CHAR:
-       case MONO_TYPE_U2:
-       case MONO_TYPE_I2:
-               swap_with_size (p, argval, 2, 1);
-               p += 2;
-               break;
-       case MONO_TYPE_U4:
-       case MONO_TYPE_I4:
-       case MONO_TYPE_R4:
-               swap_with_size (p, argval, 4, 1);
-               p += 4;
-               break;
-       case MONO_TYPE_R8:
-               swap_with_size (p, argval, 8, 1);
-               p += 8;
-               break;
-       case MONO_TYPE_U8:
-       case MONO_TYPE_I8:
-               swap_with_size (p, argval, 8, 1);
-               p += 8;
-               break;
-       case MONO_TYPE_VALUETYPE:
-               if (type->data.klass->enumtype) {
-                       simple_type = mono_class_enum_basetype (type->data.klass)->type;
-                       goto handle_enum;
-               } else {
-                       g_warning ("generic valutype %s not handled in custom attr value decoding", type->data.klass->name);
-               }
-               break;
-       case MONO_TYPE_STRING: {
-               char *str;
-               guint32 slen;
-               if (!arg) {
-                       *p++ = 0xFF;
-                       break;
-               }
-               str = mono_string_to_utf8_checked ((MonoString*)arg, error);
-               return_if_nok (error);
-               slen = strlen (str);
-               if ((p-buffer) + 10 + slen >= *buflen) {
-                       char *newbuf;
-                       *buflen *= 2;
-                       *buflen += slen;
-                       newbuf = (char *)g_realloc (buffer, *buflen);
-                       p = newbuf + (p-buffer);
-                       buffer = newbuf;
-               }
-               mono_metadata_encode_value (slen, p, &p);
-               memcpy (p, str, slen);
-               p += slen;
-               g_free (str);
-               break;
-       }
-       case MONO_TYPE_CLASS: {
-               char *str;
-               guint32 slen;
-               MonoType *arg_type;
-               if (!arg) {
-                       *p++ = 0xFF;
-                       break;
-               }
-handle_type:
-               arg_type = mono_reflection_type_get_handle ((MonoReflectionType*)arg, error);
-               return_if_nok (error);
-
-               str = type_get_qualified_name (arg_type, NULL);
-               slen = strlen (str);
-               if ((p-buffer) + 10 + slen >= *buflen) {
-                       char *newbuf;
-                       *buflen *= 2;
-                       *buflen += slen;
-                       newbuf = (char *)g_realloc (buffer, *buflen);
-                       p = newbuf + (p-buffer);
-                       buffer = newbuf;
-               }
-               mono_metadata_encode_value (slen, p, &p);
-               memcpy (p, str, slen);
-               p += slen;
-               g_free (str);
-               break;
-       }
-       case MONO_TYPE_SZARRAY: {
-               int len, i;
-               MonoClass *eclass, *arg_eclass;
-
-               if (!arg) {
-                       *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p++ = 0xff;
-                       break;
-               }
-               len = mono_array_length ((MonoArray*)arg);
-               *p++ = len & 0xff;
-               *p++ = (len >> 8) & 0xff;
-               *p++ = (len >> 16) & 0xff;
-               *p++ = (len >> 24) & 0xff;
-               *retp = p;
-               *retbuffer = buffer;
-               eclass = type->data.klass;
-               arg_eclass = mono_object_class (arg)->element_class;
-
-               if (!eclass) {
-                       /* Happens when we are called from the MONO_TYPE_OBJECT case below */
-                       eclass = mono_defaults.object_class;
-               }
-               if (eclass == mono_defaults.object_class && arg_eclass->valuetype) {
-                       char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
-                       int elsize = mono_class_array_element_size (arg_eclass);
-                       for (i = 0; i < len; ++i) {
-                               encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &arg_eclass->byval_arg, NULL, elptr, error);
-                               return_if_nok (error);
-                               elptr += elsize;
-                       }
-               } else if (eclass->valuetype && arg_eclass->valuetype) {
-                       char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
-                       int elsize = mono_class_array_element_size (eclass);
-                       for (i = 0; i < len; ++i) {
-                               encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, NULL, elptr, error);
-                               return_if_nok (error);
-                               elptr += elsize;
-                       }
-               } else {
-                       for (i = 0; i < len; ++i) {
-                               encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i), NULL, error);
-                               return_if_nok (error);
-                       }
-               }
-               break;
-       }
-       case MONO_TYPE_OBJECT: {
-               MonoClass *klass;
-               char *str;
-               guint32 slen;
-
-               /*
-                * The parameter type is 'object' but the type of the actual
-                * argument is not. So we have to add type information to the blob
-                * too. This is completely undocumented in the spec.
-                */
-
-               if (arg == NULL) {
-                       *p++ = MONO_TYPE_STRING;        // It's same hack as MS uses
-                       *p++ = 0xFF;
-                       break;
-               }
-               
-               klass = mono_object_class (arg);
-
-               if (mono_object_isinst_checked (arg, mono_defaults.systemtype_class, error)) {
-                       *p++ = 0x50;
-                       goto handle_type;
-               } else {
-                       return_if_nok (error);
-               }
-
-               if (klass->enumtype) {
-                       *p++ = 0x55;
-               } else if (klass == mono_defaults.string_class) {
-                       simple_type = MONO_TYPE_STRING;
-                       *p++ = 0x0E;
-                       goto handle_enum;
-               } else if (klass->rank == 1) {
-                       *p++ = 0x1D;
-                       if (klass->element_class->byval_arg.type == MONO_TYPE_OBJECT)
-                               /* See Partition II, Appendix B3 */
-                               *p++ = 0x51;
-                       else
-                               *p++ = klass->element_class->byval_arg.type;
-                       encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &klass->byval_arg, arg, NULL, error);
-                       return_if_nok (error);
-                       break;
-               } else if (klass->byval_arg.type >= MONO_TYPE_BOOLEAN && klass->byval_arg.type <= MONO_TYPE_R8) {
-                       *p++ = simple_type = klass->byval_arg.type;
-                       goto handle_enum;
-               } else {
-                       g_error ("unhandled type in custom attr");
-               }
-               str = type_get_qualified_name (mono_class_get_type(klass), NULL);
-               slen = strlen (str);
-               if ((p-buffer) + 10 + slen >= *buflen) {
-                       char *newbuf;
-                       *buflen *= 2;
-                       *buflen += slen;
-                       newbuf = (char *)g_realloc (buffer, *buflen);
-                       p = newbuf + (p-buffer);
-                       buffer = newbuf;
-               }
-               mono_metadata_encode_value (slen, p, &p);
-               memcpy (p, str, slen);
-               p += slen;
-               g_free (str);
-               simple_type = mono_class_enum_basetype (klass)->type;
-               goto handle_enum;
-       }
-       default:
-               g_error ("type 0x%02x not yet supported in custom attr encoder", simple_type);
-       }
-       *retp = p;
-       *retbuffer = buffer;
-}
-
-static void
-encode_field_or_prop_type (MonoType *type, char *p, char **retp)
-{
-       if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
-               char *str = type_get_qualified_name (type, NULL);
-               int slen = strlen (str);
-
-               *p++ = 0x55;
-               /*
-                * This seems to be optional...
-                * *p++ = 0x80;
-                */
-               mono_metadata_encode_value (slen, p, &p);
-               memcpy (p, str, slen);
-               p += slen;
-               g_free (str);
-       } else if (type->type == MONO_TYPE_OBJECT) {
-               *p++ = 0x51;
-       } else if (type->type == MONO_TYPE_CLASS) {
-               /* it should be a type: encode_cattr_value () has the check */
-               *p++ = 0x50;
-       } else {
-               mono_metadata_encode_value (type->type, p, &p);
-               if (type->type == MONO_TYPE_SZARRAY)
-                       /* See the examples in Partition VI, Annex B */
-                       encode_field_or_prop_type (&type->data.klass->byval_arg, p, &p);
-       }
-
-       *retp = p;
-}
-
-#ifndef DISABLE_REFLECTION_EMIT
-static void
-encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, char *name, MonoObject *value, MonoError *error)
-{
-       int len;
-
-       mono_error_init (error);
-
-       /* Preallocate a large enough buffer */
-       if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
-               char *str = type_get_qualified_name (type, NULL);
-               len = strlen (str);
-               g_free (str);
-       } else if (type->type == MONO_TYPE_SZARRAY && type->data.klass->enumtype) {
-               char *str = type_get_qualified_name (&type->data.klass->byval_arg, NULL);
-               len = strlen (str);
-               g_free (str);
-       } else {
-               len = 0;
-       }
-       len += strlen (name);
-
-       if ((p-buffer) + 20 + len >= *buflen) {
-               char *newbuf;
-               *buflen *= 2;
-               *buflen += len;
-               newbuf = (char *)g_realloc (buffer, *buflen);
-               p = newbuf + (p-buffer);
-               buffer = newbuf;
-       }
-
-       encode_field_or_prop_type (type, p, &p);
-
-       len = strlen (name);
-       mono_metadata_encode_value (len, p, &p);
-       memcpy (p, name, len);
-       p += len;
-       encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, buflen, type, value, NULL, error);
-       return_if_nok (error);
-       *retp = p;
-       *retbuffer = buffer;
-}
-
-/**
- * mono_reflection_get_custom_attrs_blob:
- * @ctor: custom attribute constructor
- * @ctorArgs: arguments o the constructor
- * @properties:
- * @propValues:
- * @fields:
- * @fieldValues:
- * 
- * Creates the blob of data that needs to be saved in the metadata and that represents
- * the custom attributed described by @ctor, @ctorArgs etc.
- * Returns: a Byte array representing the blob of data.
- */
-MonoArray*
-mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) 
-{
-       MonoError error;
-       MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
-       mono_error_cleanup (&error);
-       return result;
-}
-
-/**
- * mono_reflection_get_custom_attrs_blob_checked:
- * @ctor: custom attribute constructor
- * @ctorArgs: arguments o the constructor
- * @properties:
- * @propValues:
- * @fields:
- * @fieldValues:
- * @error: set on error
- * 
- * Creates the blob of data that needs to be saved in the metadata and that represents
- * the custom attributed described by @ctor, @ctorArgs etc.
- * Returns: a Byte array representing the blob of data.  On failure returns NULL and sets @error.
- */
-MonoArray*
-mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues, MonoError *error) 
-{
-       MonoArray *result = NULL;
-       MonoMethodSignature *sig;
-       MonoObject *arg;
-       char *buffer, *p;
-       guint32 buflen, i;
-
-       mono_error_init (error);
-
-       if (strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
-               /* sig is freed later so allocate it in the heap */
-               sig = ctor_builder_to_signature (NULL, (MonoReflectionCtorBuilder*)ctor, error);
-               if (!is_ok (error)) {
-                       g_free (sig);
-                       return NULL;
-               }
-       } else {
-               sig = mono_method_signature (((MonoReflectionMethod*)ctor)->method);
-       }
-
-       g_assert (mono_array_length (ctorArgs) == sig->param_count);
-       buflen = 256;
-       p = buffer = (char *)g_malloc (buflen);
-       /* write the prolog */
-       *p++ = 1;
-       *p++ = 0;
-       for (i = 0; i < sig->param_count; ++i) {
-               arg = mono_array_get (ctorArgs, MonoObject*, i);
-               encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, sig->params [i], arg, NULL, error);
-               if (!is_ok (error)) goto leave;
-       }
-       i = 0;
-       if (properties)
-               i += mono_array_length (properties);
-       if (fields)
-               i += mono_array_length (fields);
-       *p++ = i & 0xff;
-       *p++ = (i >> 8) & 0xff;
-       if (properties) {
-               MonoObject *prop;
-               for (i = 0; i < mono_array_length (properties); ++i) {
-                       MonoType *ptype;
-                       char *pname;
-
-                       prop = (MonoObject *)mono_array_get (properties, gpointer, i);
-                       get_prop_name_and_type (prop, &pname, &ptype, error);
-                       if (!is_ok (error)) goto leave;
-                       *p++ = 0x54; /* PROPERTY signature */
-                       encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ptype, pname, (MonoObject*)mono_array_get (propValues, gpointer, i), error);
-                       g_free (pname);
-                       if (!is_ok (error)) goto leave;
-               }
-       }
-
-       if (fields) {
-               MonoObject *field;
-               for (i = 0; i < mono_array_length (fields); ++i) {
-                       MonoType *ftype;
-                       char *fname;
-
-                       field = (MonoObject *)mono_array_get (fields, gpointer, i);
-                       get_field_name_and_type (field, &fname, &ftype, error);
-                       if (!is_ok (error)) goto leave;
-                       *p++ = 0x53; /* FIELD signature */
-                       encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ftype, fname, (MonoObject*)mono_array_get (fieldValues, gpointer, i), error);
-                       g_free (fname);
-                       if (!is_ok (error)) goto leave;
-               }
-       }
-
-       g_assert (p - buffer <= buflen);
-       buflen = p - buffer;
-       result = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, buflen, error);
-       if (!is_ok (error))
-               goto leave;
-       p = mono_array_addr (result, char, 0);
-       memcpy (p, buffer, buflen);
-leave:
-       g_free (buffer);
-       if (strcmp (ctor->vtable->klass->name, "MonoCMethod"))
-               g_free (sig);
-       return result;
-}
-
-/**
- * reflection_setup_internal_class:
- * @tb: a TypeBuilder object
- * @error: set on error
- *
- * Creates a MonoClass that represents the TypeBuilder.
- * This is a trick that lets us simplify a lot of reflection code
- * (and will allow us to support Build and Run assemblies easier).
- *
- * Returns TRUE on success. On failure, returns FALSE and sets @error.
- */
-static gboolean
-reflection_setup_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error)
-{
-       MonoClass *klass, *parent;
-
-       mono_error_init (error);
-       RESOLVE_TYPE (tb->parent, error);
-       return_val_if_nok (error, FALSE);
-
-       mono_loader_lock ();
-
-       if (tb->parent) {
-               MonoType *parent_type = mono_reflection_type_get_handle ((MonoReflectionType*)tb->parent, error);
-               if (!is_ok (error)) {
-                       mono_loader_unlock ();
-                       return FALSE;
-               }
-               /* check so we can compile corlib correctly */
-               if (strcmp (mono_object_class (tb->parent)->name, "TypeBuilder") == 0) {
-                       /* mono_class_setup_mono_type () guaranteess type->data.klass is valid */
-                       parent = parent_type->data.klass;
-               } else {
-                       parent = mono_class_from_mono_type (parent_type);
-               }
-       } else {
-               parent = NULL;
-       }
-       
-       /* the type has already being created: it means we just have to change the parent */
-       if (tb->type.type) {
-               klass = mono_class_from_mono_type (tb->type.type);
-               klass->parent = NULL;
-               /* fool mono_class_setup_parent */
-               klass->supertypes = NULL;
-               mono_class_setup_parent (klass, parent);
-               mono_class_setup_mono_type (klass);
-               mono_loader_unlock ();
-               return TRUE;
-       }
-
-       klass = (MonoClass *)mono_image_alloc0 (&tb->module->dynamic_image->image, sizeof (MonoClass));
-
-       klass->image = &tb->module->dynamic_image->image;
-
-       klass->inited = 1; /* we lie to the runtime */
-       klass->name = mono_string_to_utf8_image (klass->image, tb->name, error);
-       if (!is_ok (error))
-               goto failure;
-       klass->name_space = mono_string_to_utf8_image (klass->image, tb->nspace, error);
-       if (!is_ok (error))
-               goto failure;
-       klass->type_token = MONO_TOKEN_TYPE_DEF | tb->table_idx;
-       klass->flags = tb->attrs;
-       
-       mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD);
-
-       klass->element_class = klass;
-
-       if (mono_class_get_ref_info (klass) == NULL) {
-
-               mono_class_set_ref_info (klass, tb);
-
-               /* Put into cache so mono_class_get_checked () will find it.
-               Skip nested types as those should not be available on the global scope. */
-               if (!tb->nesting_type)
-                       mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, tb->table_idx);
-
-               /*
-               We must register all types as we cannot rely on the name_cache hashtable since we find the class
-               by performing a mono_class_get which does the full resolution.
-
-               Working around this semantics would require us to write a lot of code for no clear advantage.
-               */
-               mono_image_append_class_to_reflection_info_set (klass);
-       } else {
-               g_assert (mono_class_get_ref_info (klass) == tb);
-       }
-
-       register_dyn_token (tb->module->dynamic_image, MONO_TOKEN_TYPE_DEF | tb->table_idx, (MonoObject*)tb);
-
-       if (parent != NULL) {
-               mono_class_setup_parent (klass, parent);
-       } else if (strcmp (klass->name, "Object") == 0 && strcmp (klass->name_space, "System") == 0) {
-               const char *old_n = klass->name;
-               /* trick to get relative numbering right when compiling corlib */
-               klass->name = "BuildingObject";
-               mono_class_setup_parent (klass, mono_defaults.object_class);
-               klass->name = old_n;
-       }
-
-       if ((!strcmp (klass->name, "ValueType") && !strcmp (klass->name_space, "System")) ||
-                       (!strcmp (klass->name, "Object") && !strcmp (klass->name_space, "System")) ||
-                       (!strcmp (klass->name, "Enum") && !strcmp (klass->name_space, "System"))) {
-               klass->instance_size = sizeof (MonoObject);
-               klass->size_inited = 1;
-               mono_class_setup_vtable_general (klass, NULL, 0, NULL);
-       }
-
-       mono_class_setup_mono_type (klass);
-
-       mono_class_setup_supertypes (klass);
-
-       /*
-        * FIXME: handle interfaces.
-        */
-
-       tb->type.type = &klass->byval_arg;
-
-       if (tb->nesting_type) {
-               g_assert (tb->nesting_type->type);
-               MonoType *nesting_type = mono_reflection_type_get_handle (tb->nesting_type, error);
-               if (!is_ok (error)) goto failure;
-               klass->nested_in = mono_class_from_mono_type (nesting_type);
-       }
-
-       /*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
-
-       mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
-       
-       mono_loader_unlock ();
-       return TRUE;
-
-failure:
-       mono_loader_unlock ();
-       return FALSE;
-}
-
-/**
- * ves_icall_TypeBuilder_setup_internal_class:
- * @tb: a TypeBuilder object
- *
- * (icall)
- * Creates a MonoClass that represents the TypeBuilder.
- * This is a trick that lets us simplify a lot of reflection code
- * (and will allow us to support Build and Run assemblies easier).
- *
- */
-void
-ves_icall_TypeBuilder_setup_internal_class (MonoReflectionTypeBuilder *tb)
-{
-       MonoError error;
-       (void) reflection_setup_internal_class (tb, &error);
-       mono_error_set_pending_exception (&error);
-}
-
-/*
- * ves_icall_TypeBuilder_setup_generic_class:
- * @tb: a TypeBuilder object
- *
- * Setup the generic class before adding the first generic parameter.
- */
-void
-ves_icall_TypeBuilder_setup_generic_class (MonoReflectionTypeBuilder *tb)
-{
-}
-
-/**
- * mono_reflection_create_generic_class:
- * @tb: a TypeBuilder object
- * @error: set on error
- *
- * Creates the generic class after all generic parameters have been added.
- * On success returns TRUE, on failure returns FALSE and sets @error.
- * 
- */
-static gboolean
-mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error)
-{
-
-       MonoClass *klass;
-       int count, i;
-
-       mono_error_init (error);
-
-       klass = mono_class_from_mono_type (tb->type.type);
-
-       count = tb->generic_params ? mono_array_length (tb->generic_params) : 0;
-
-       if (klass->generic_container || (count == 0))
-               return TRUE;
-
-       g_assert (tb->generic_container && (tb->generic_container->owner.klass == klass));
-
-       klass->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
-
-       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->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;
-               /*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;
-
-               g_assert (klass->generic_container->type_params [i].param.owner);
-       }
-
-       klass->generic_container->context.class_inst = mono_get_shared_generic_inst (klass->generic_container);
-       return TRUE;
-}
-
-/**
- * reflection_create_internal_class:
- * @tb: a TypeBuilder object
- * @error: set on error
- *
- * Actually create the MonoClass that is associated with the TypeBuilder.
- * On success returns TRUE, on failure returns FALSE and sets @error.
- *
- */
-static gboolean
-reflection_create_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error)
-{
-       MonoClass *klass;
-
-       mono_error_init (error);
-       klass = mono_class_from_mono_type (tb->type.type);
-
-       mono_loader_lock ();
-       if (klass->enumtype && mono_class_enum_basetype (klass) == NULL) {
-               MonoReflectionFieldBuilder *fb;
-               MonoClass *ec;
-               MonoType *enum_basetype;
-
-               g_assert (tb->fields != NULL);
-               g_assert (mono_array_length (tb->fields) >= 1);
-
-               fb = mono_array_get (tb->fields, MonoReflectionFieldBuilder*, 0);
-
-               MonoType *field_type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
-               if (!is_ok (error)) {
-                       mono_loader_unlock ();
-                       return FALSE;
-               }
-               if (!mono_type_is_valid_enum_basetype (field_type)) {
-                       mono_loader_unlock ();
-                       return TRUE;
-               }
-
-               enum_basetype = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
-               if (!is_ok (error)) {
-                       mono_loader_unlock ();
-                       return FALSE;
-               }
-               klass->element_class = mono_class_from_mono_type (enum_basetype);
-               if (!klass->element_class)
-                       klass->element_class = mono_class_from_mono_type (enum_basetype);
-
-               /*
-                * get the element_class from the current corlib.
-                */
-               ec = default_class_from_mono_type (enum_basetype);
-               klass->instance_size = ec->instance_size;
-               klass->size_inited = 1;
-               /* 
-                * this is almost safe to do with enums and it's needed to be able
-                * to create objects of the enum type (for use in SetConstant).
-                */
-               /* FIXME: Does this mean enums can't have method overrides ? */
-               mono_class_setup_vtable_general (klass, NULL, 0, NULL);
-       }
-       mono_loader_unlock ();
-       return TRUE;
-}
-
-/**
- * ves_icall_TypeBuilder_create_internal_class:
- * @tb: a TypeBuilder object
- *
- * (icall)
- * Actually create the MonoClass that is associated with the TypeBuilder.
- */
-void
-ves_icall_TypeBuilder_create_internal_class (MonoReflectionTypeBuilder *tb)
-{
-       MonoError error;
-       (void) reflection_create_internal_class (tb, &error);
-       mono_error_set_pending_exception (&error);
-}
-
-static MonoMarshalSpec*
-mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
-                               MonoReflectionMarshal *minfo, MonoError *error)
-{
-       MonoMarshalSpec *res;
-
-       mono_error_init (error);
-
-       res = image_g_new0 (image, MonoMarshalSpec, 1);
-       res->native = (MonoMarshalNative)minfo->type;
-
-       switch (minfo->type) {
-       case MONO_NATIVE_LPARRAY:
-               res->data.array_data.elem_type = (MonoMarshalNative)minfo->eltype;
-               if (minfo->has_size) {
-                       res->data.array_data.param_num = minfo->param_num;
-                       res->data.array_data.num_elem = minfo->count;
-                       res->data.array_data.elem_mult = minfo->param_num == -1 ? 0 : 1;
-               }
-               else {
-                       res->data.array_data.param_num = -1;
-                       res->data.array_data.num_elem = -1;
-                       res->data.array_data.elem_mult = -1;
-               }
-               break;
-
-       case MONO_NATIVE_BYVALTSTR:
-       case MONO_NATIVE_BYVALARRAY:
-               res->data.array_data.num_elem = minfo->count;
-               break;
-
-       case MONO_NATIVE_CUSTOM:
-               if (minfo->marshaltyperef) {
-                       MonoType *marshaltyperef = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
-                       if (!is_ok (error)) {
-                               image_g_free (image, res);
-                               return NULL;
-                       }
-                       res->data.custom_data.custom_name =
-                               type_get_fully_qualified_name (marshaltyperef);
-               }
-               if (minfo->mcookie) {
-                       res->data.custom_data.cookie = mono_string_to_utf8_checked (minfo->mcookie, error);
-                       if (!is_ok (error)) {
-                               image_g_free (image, res);
-                               return NULL;
-                       }
-               }
-               break;
-
-       default:
-               break;
-       }
-
-       return res;
-}
-#endif /* !DISABLE_REFLECTION_EMIT */
-
-MonoReflectionMarshalAsAttribute*
-mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
-                                                       MonoMarshalSpec *spec, MonoError *error)
-{
-       MonoReflectionType *rt;
-       MonoReflectionMarshalAsAttribute *minfo;
-       MonoType *mtype;
-
-       mono_error_init (error);
-       
-       minfo = (MonoReflectionMarshalAsAttribute*)mono_object_new_checked (domain, mono_class_get_marshal_as_attribute_class (), error);
-       if (!minfo)
-               return NULL;
-       minfo->utype = spec->native;
-
-       switch (minfo->utype) {
-       case MONO_NATIVE_LPARRAY:
-               minfo->array_subtype = spec->data.array_data.elem_type;
-               minfo->size_const = spec->data.array_data.num_elem;
-               if (spec->data.array_data.param_num != -1)
-                       minfo->size_param_index = spec->data.array_data.param_num;
-               break;
-
-       case MONO_NATIVE_BYVALTSTR:
-       case MONO_NATIVE_BYVALARRAY:
-               minfo->size_const = spec->data.array_data.num_elem;
-               break;
-
-       case MONO_NATIVE_CUSTOM:
-               if (spec->data.custom_data.custom_name) {
-                       mtype = mono_reflection_type_from_name_checked (spec->data.custom_data.custom_name, klass->image, error);
-                       return_val_if_nok  (error, NULL);
-
-                       if (mtype) {
-                               rt = mono_type_get_object_checked (domain, mtype, error);
-                               if (!rt)
-                                       return NULL;
-
-                               MONO_OBJECT_SETREF (minfo, marshal_type_ref, rt);
-                       }
-
-                       MONO_OBJECT_SETREF (minfo, marshal_type, mono_string_new (domain, spec->data.custom_data.custom_name));
-               }
-               if (spec->data.custom_data.cookie)
-                       MONO_OBJECT_SETREF (minfo, marshal_cookie, mono_string_new (domain, spec->data.custom_data.cookie));
-               break;
-
-       default:
-               break;
-       }
-
-       return minfo;
-}
-
-#ifndef DISABLE_REFLECTION_EMIT
-static MonoMethod*
-reflection_methodbuilder_to_mono_method (MonoClass *klass,
-                                        ReflectionMethodBuilder *rmb,
-                                        MonoMethodSignature *sig,
-                                        MonoError *error)
-{
-       MonoMethod *m;
-       MonoMethodWrapper *wrapperm;
-       MonoMarshalSpec **specs;
-       MonoReflectionMethodAux *method_aux;
-       MonoImage *image;
-       gboolean dynamic;
-       int i;
-
-       mono_error_init (error);
-       /*
-        * Methods created using a MethodBuilder should have their memory allocated
-        * inside the image mempool, while dynamic methods should have their memory
-        * malloc'd.
-        */
-       dynamic = rmb->refs != NULL;
-       image = dynamic ? NULL : klass->image;
-
-       if (!dynamic)
-               g_assert (!klass->generic_class);
-
-       mono_loader_lock ();
-
-       if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
-                       (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
-               m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1);
-       else
-               m = (MonoMethod *)image_g_new0 (image, MonoMethodWrapper, 1);
-
-       wrapperm = (MonoMethodWrapper*)m;
-
-       m->dynamic = dynamic;
-       m->slot = -1;
-       m->flags = rmb->attrs;
-       m->iflags = rmb->iattrs;
-       m->name = mono_string_to_utf8_image_ignore (image, rmb->name);
-       m->klass = klass;
-       m->signature = sig;
-       m->sre_method = TRUE;
-       m->skip_visibility = rmb->skip_visibility;
-       if (rmb->table_idx)
-               m->token = MONO_TOKEN_METHOD_DEF | (*rmb->table_idx);
-
-       if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
-               if (klass == mono_defaults.string_class && !strcmp (m->name, ".ctor"))
-                       m->string_ctor = 1;
-
-               m->signature->pinvoke = 1;
-       } else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
-               m->signature->pinvoke = 1;
-
-               method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
-
-               method_aux->dllentry = rmb->dllentry ? mono_string_to_utf8_image (image, rmb->dllentry, error) : image_strdup (image, m->name);
-               mono_error_assert_ok (error);
-               method_aux->dll = mono_string_to_utf8_image (image, rmb->dll, error);
-               mono_error_assert_ok (error);
-               
-               ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags;
-
-               if (image_is_dynamic (klass->image))
-                       g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
-
-               mono_loader_unlock ();
-
-               return m;
-       } else if (!(m->flags & METHOD_ATTRIBUTE_ABSTRACT) &&
-                          !(m->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
-               MonoMethodHeader *header;
-               guint32 code_size;
-               gint32 max_stack, i;
-               gint32 num_locals = 0;
-               gint32 num_clauses = 0;
-               guint8 *code;
-
-               if (rmb->ilgen) {
-                       code = mono_array_addr (rmb->ilgen->code, guint8, 0);
-                       code_size = rmb->ilgen->code_len;
-                       max_stack = rmb->ilgen->max_stack;
-                       num_locals = rmb->ilgen->locals ? mono_array_length (rmb->ilgen->locals) : 0;
-                       if (rmb->ilgen->ex_handlers)
-                               num_clauses = method_count_clauses (rmb->ilgen);
-               } else {
-                       if (rmb->code) {
-                               code = mono_array_addr (rmb->code, guint8, 0);
-                               code_size = mono_array_length (rmb->code);
-                               /* we probably need to run a verifier on the code... */
-                               max_stack = 8; 
-                       }
-                       else {
-                               code = NULL;
-                               code_size = 0;
-                               max_stack = 8;
-                       }
-               }
-
-               header = (MonoMethodHeader *)image_g_malloc0 (image, MONO_SIZEOF_METHOD_HEADER + num_locals * sizeof (MonoType*));
-               header->code_size = code_size;
-               header->code = (const unsigned char *)image_g_malloc (image, code_size);
-               memcpy ((char*)header->code, code, code_size);
-               header->max_stack = max_stack;
-               header->init_locals = rmb->init_locals;
-               header->num_locals = num_locals;
-
-               for (i = 0; i < num_locals; ++i) {
-                       MonoReflectionLocalBuilder *lb = 
-                               mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
-
-                       header->locals [i] = image_g_new0 (image, MonoType, 1);
-                       MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)lb->type, error);
-                       mono_error_assert_ok (error);
-                       memcpy (header->locals [i], type, MONO_SIZEOF_TYPE);
-               }
-
-               header->num_clauses = num_clauses;
-               if (num_clauses) {
-                       header->clauses = method_encode_clauses (image, (MonoDynamicImage*)klass->image,
-                                                                rmb->ilgen, num_clauses, error);
-                       mono_error_assert_ok (error);
-               }
-
-               wrapperm->header = header;
-       }
-
-       if (rmb->generic_params) {
-               int count = mono_array_length (rmb->generic_params);
-               MonoGenericContainer *container = rmb->generic_container;
-
-               g_assert (container);
-
-               container->type_argc = count;
-               container->type_params = image_g_new0 (image, MonoGenericParamFull, count);
-               container->owner.method = m;
-               container->is_anonymous = FALSE; // Method is now known, container is no longer anonymous
-
-               m->is_generic = TRUE;
-               mono_method_set_generic_container (m, container);
-
-               for (i = 0; i < count; i++) {
-                       MonoReflectionGenericParam *gp =
-                               mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
-                       MonoType *gp_type = mono_reflection_type_get_handle ((MonoReflectionType*)gp, error);
-                       mono_error_assert_ok (error);
-                       MonoGenericParamFull *param = (MonoGenericParamFull *) gp_type->data.generic_param;
-                       container->type_params [i] = *param;
-               }
-
-               /*
-                * The method signature might have pointers to generic parameters that belong to other methods.
-                * This is a valid SRE case, but the resulting method signature must be encoded using the proper
-                * generic parameters.
-                */
-               for (i = 0; i < m->signature->param_count; ++i) {
-                       MonoType *t = m->signature->params [i];
-                       if (t->type == MONO_TYPE_MVAR) {
-                               MonoGenericParam *gparam =  t->data.generic_param;
-                               if (gparam->num < count) {
-                                       m->signature->params [i] = mono_metadata_type_dup (image, m->signature->params [i]);
-                                       m->signature->params [i]->data.generic_param = mono_generic_container_get_param (container, gparam->num);
-                               }
-
-                       }
-               }
-
-               if (klass->generic_container) {
-                       container->parent = klass->generic_container;
-                       container->context.class_inst = klass->generic_container->context.class_inst;
-               }
-               container->context.method_inst = mono_get_shared_generic_inst (container);
-       }
-
-       if (rmb->refs) {
-               MonoMethodWrapper *mw = (MonoMethodWrapper*)m;
-               int i;
-               void **data;
-
-               m->wrapper_type = MONO_WRAPPER_DYNAMIC_METHOD;
-
-               mw->method_data = data = image_g_new (image, gpointer, rmb->nrefs + 1);
-               data [0] = GUINT_TO_POINTER (rmb->nrefs);
-               for (i = 0; i < rmb->nrefs; ++i)
-                       data [i + 1] = rmb->refs [i];
-       }
-
-       method_aux = NULL;
-
-       /* Parameter info */
-       if (rmb->pinfo) {
-               if (!method_aux)
-                       method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
-               method_aux->param_names = image_g_new0 (image, char *, mono_method_signature (m)->param_count + 1);
-               for (i = 0; i <= m->signature->param_count; ++i) {
-                       MonoReflectionParamBuilder *pb;
-                       if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
-                               if ((i > 0) && (pb->attrs)) {
-                                       /* Make a copy since it might point to a shared type structure */
-                                       m->signature->params [i - 1] = mono_metadata_type_dup (klass->image, m->signature->params [i - 1]);
-                                       m->signature->params [i - 1]->attrs = pb->attrs;
-                               }
-
-                               if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
-                                       MonoDynamicImage *assembly;
-                                       guint32 idx, len;
-                                       MonoTypeEnum def_type;
-                                       char *p;
-                                       const char *p2;
-
-                                       if (!method_aux->param_defaults) {
-                                               method_aux->param_defaults = image_g_new0 (image, guint8*, m->signature->param_count + 1);
-                                               method_aux->param_default_types = image_g_new0 (image, guint32, m->signature->param_count + 1);
-                                       }
-                                       assembly = (MonoDynamicImage*)klass->image;
-                                       idx = encode_constant (assembly, pb->def_value, &def_type);
-                                       /* Copy the data from the blob since it might get realloc-ed */
-                                       p = assembly->blob.data + idx;
-                                       len = mono_metadata_decode_blob_size (p, &p2);
-                                       len += p2 - p;
-                                       method_aux->param_defaults [i] = (uint8_t *)image_g_malloc (image, len);
-                                       method_aux->param_default_types [i] = def_type;
-                                       memcpy ((gpointer)method_aux->param_defaults [i], p, len);
-                               }
-
-                               if (pb->name) {
-                                       method_aux->param_names [i] = mono_string_to_utf8_image (image, pb->name, error);
-                                       mono_error_assert_ok (error);
-                               }
-                               if (pb->cattrs) {
-                                       if (!method_aux->param_cattr)
-                                               method_aux->param_cattr = image_g_new0 (image, MonoCustomAttrInfo*, m->signature->param_count + 1);
-                                       method_aux->param_cattr [i] = mono_custom_attrs_from_builders (image, klass->image, pb->cattrs);
-                               }
-                       }
-               }
-       }
-
-       /* Parameter marshalling */
-       specs = NULL;
-       if (rmb->pinfo)         
-               for (i = 0; i < mono_array_length (rmb->pinfo); ++i) {
-                       MonoReflectionParamBuilder *pb;
-                       if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
-                               if (pb->marshal_info) {
-                                       if (specs == NULL)
-                                               specs = image_g_new0 (image, MonoMarshalSpec*, sig->param_count + 1);
-                                       specs [pb->position] = 
-                                               mono_marshal_spec_from_builder (image, klass->image->assembly, pb->marshal_info, error);
-                                       if (!is_ok (error)) {
-                                               mono_loader_unlock ();
-                                               image_g_free (image, specs);
-                                               /* FIXME: if image is NULL, this leaks all the other stuff we alloc'd in this function */
-                                               return NULL;
-                                       }
-                               }
-                       }
-               }
-       if (specs != NULL) {
-               if (!method_aux)
-                       method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
-               method_aux->param_marshall = specs;
-       }
-
-       if (image_is_dynamic (klass->image) && method_aux)
-               g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
-
-       mono_loader_unlock ();
-
-       return m;
-}      
-
-static MonoMethod*
-ctorbuilder_to_mono_method (MonoClass *klass, MonoReflectionCtorBuilder* mb, MonoError *error)
-{
-       ReflectionMethodBuilder rmb;
-       MonoMethodSignature *sig;
-
-       mono_loader_lock ();
-       g_assert (klass->image != NULL);
-       sig = ctor_builder_to_signature (klass->image, mb, error);
-       mono_loader_unlock ();
-       return_val_if_nok (error, NULL);
-
-       if (!reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
-               return NULL;
-
-       mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
-       return_val_if_nok (error, NULL);
-       mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
-
-       /* If we are in a generic class, we might be called multiple times from inflate_method */
-       if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save && !klass->generic_container) {
-               /* ilgen is no longer needed */
-               mb->ilgen = NULL;
-       }
-
-       return mb->mhandle;
-}
-
-static MonoMethod*
-methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilder* mb, MonoError *error)
-{
-       ReflectionMethodBuilder rmb;
-       MonoMethodSignature *sig;
-
-       mono_error_init (error);
-
-       mono_loader_lock ();
-       g_assert (klass->image != NULL);
-       sig = method_builder_to_signature (klass->image, mb, error);
-       mono_loader_unlock ();
-       return_val_if_nok (error, NULL);
-
-       if (!reflection_methodbuilder_from_method_builder (&rmb, mb, error))
-               return NULL;
-
-       mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
-       return_val_if_nok (error, NULL);
-       mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
-
-       /* If we are in a generic class, we might be called multiple times from inflate_method */
-       if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save && !klass->generic_container) {
-               /* ilgen is no longer needed */
-               mb->ilgen = NULL;
-       }
-       return mb->mhandle;
-}
-
-static MonoClassField*
-fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder* fb, MonoError *error)
-{
-       MonoClassField *field;
-       MonoType *custom;
-
-       mono_error_init (error);
-
-       field = g_new0 (MonoClassField, 1);
-
-       field->name = mono_string_to_utf8_image (klass->image, fb->name, error);
-       mono_error_assert_ok (error);
-       if (fb->attrs || fb->modreq || fb->modopt) {
-               MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
-               if (!is_ok (error)) {
-                       g_free (field);
-                       return NULL;
-               }
-               field->type = mono_metadata_type_dup (NULL, type);
-               field->type->attrs = fb->attrs;
-
-               g_assert (image_is_dynamic (klass->image));
-               custom = add_custom_modifiers ((MonoDynamicImage*)klass->image, field->type, fb->modreq, fb->modopt, error);
-               g_free (field->type);
-               if (!is_ok (error)) {
-                       g_free (field);
-                       return NULL;
-               }
-               field->type = mono_metadata_type_dup (klass->image, custom);
-               g_free (custom);
-       } else {
-               field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
-               if (!is_ok (error)) {
-                       g_free (field);
-                       return NULL;
-               }
-       }
-       if (fb->offset != -1)
-               field->offset = fb->offset;
-       field->parent = klass;
-       mono_save_custom_attrs (klass->image, field, fb->cattrs);
-
-       // FIXME: Can't store fb->def_value/RVA, is it needed for field_on_insts ?
-
-       return field;
-}
-#endif
-
-/**
- * mono_reflection_bind_generic_parameters:
- * @type: a managed type object (which should be some kind of generic (instance? definition?))
- * @type_args: the number of type arguments to bind
- * @types: array of type arguments
- * @error: set on error
- *
- * Given a managed type object for a generic type instance, binds each of its arguments to the specified types.
- * Returns the MonoType* for the resulting type instantiation.  On failure returns NULL and sets @error.
- */
-MonoType*
-mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types, MonoError *error)
-{
-       MonoClass *klass;
-       MonoReflectionTypeBuilder *tb = NULL;
-       gboolean is_dynamic = FALSE;
-       MonoClass *geninst;
-
-       mono_error_init (error);
-       
-       mono_loader_lock ();
-
-       if (is_sre_type_builder (mono_object_class (type))) {
-               tb = (MonoReflectionTypeBuilder *) type;
-
-               is_dynamic = TRUE;
-       } else if (is_sre_generic_instance (mono_object_class (type))) {
-               MonoReflectionGenericClass *rgi = (MonoReflectionGenericClass *) type;
-               MonoReflectionType *gtd = rgi->generic_type;
-
-               if (is_sre_type_builder (mono_object_class (gtd))) {
-                       tb = (MonoReflectionTypeBuilder *)gtd;
-                       is_dynamic = TRUE;
-               }
-       }
-
-       /* FIXME: fix the CreateGenericParameters protocol to avoid the two stage setup of TypeBuilders */
-       if (tb && tb->generic_container) {
-               if (!mono_reflection_create_generic_class (tb, error)) {
-                       mono_loader_unlock ();
-                       return NULL;
-               }
-       }
-
-       MonoType *t = mono_reflection_type_get_handle (type, error);
-       if (!is_ok (error)) {
-               mono_loader_unlock ();
-               return NULL;
-       }
-
-       klass = mono_class_from_mono_type (t);
-       if (!klass->generic_container) {
-               mono_loader_unlock ();
-               mono_error_set_type_load_class (error, klass, "Cannot bind generic parameters of a non-generic type");
-               return NULL;
-       }
-
-       if (klass->wastypebuilder) {
-               tb = (MonoReflectionTypeBuilder *) mono_class_get_ref_info (klass);
-
-               is_dynamic = TRUE;
-       }
-
-       mono_loader_unlock ();
-
-       geninst = mono_class_bind_generic_parameters (klass, type_argc, types, is_dynamic);
-
-       return &geninst->byval_arg;
-}
-
-MonoClass*
-mono_class_bind_generic_parameters (MonoClass *klass, int type_argc, MonoType **types, gboolean is_dynamic)
-{
-       MonoGenericClass *gclass;
-       MonoGenericInst *inst;
-
-       g_assert (klass->generic_container);
-
-       inst = mono_metadata_get_generic_inst (type_argc, types);
-       gclass = mono_metadata_lookup_generic_class (klass, inst, is_dynamic);
-
-       return mono_generic_class_get_class (gclass);
-}
-
-static MonoReflectionMethod*
-reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, MonoArray *types, MonoError *error)
-{
-       MonoClass *klass;
-       MonoMethod *method, *inflated;
-       MonoMethodInflated *imethod;
-       MonoGenericContext tmp_context;
-       MonoGenericInst *ginst;
-       MonoType **type_argv;
-       int count, i;
-
-       mono_error_init (error);
-
-       /*FIXME but this no longer should happen*/
-       if (!strcmp (rmethod->object.vtable->klass->name, "MethodBuilder")) {
-#ifndef DISABLE_REFLECTION_EMIT
-               MonoReflectionMethodBuilder *mb = NULL;
-               MonoType *tb;
-               MonoClass *klass;
-
-               mb = (MonoReflectionMethodBuilder *) rmethod;
-               tb = mono_reflection_type_get_handle ((MonoReflectionType*)mb->type, error);
-               return_val_if_nok (error, NULL);
-               klass = mono_class_from_mono_type (tb);
-
-               method = methodbuilder_to_mono_method (klass, mb, error);
-               return_val_if_nok (error, NULL);
-#else
-               g_assert_not_reached ();
-               method = NULL;
-#endif
-       } else {
-               method = rmethod->method;
-       }
-
-       klass = method->klass;
-
-       if (method->is_inflated)
-               method = ((MonoMethodInflated *) method)->declaring;
-
-       count = mono_method_signature (method)->generic_param_count;
-       if (count != mono_array_length (types))
-               return NULL;
-
-       type_argv = g_new0 (MonoType *, count);
-       for (i = 0; i < count; i++) {
-               MonoReflectionType *garg = (MonoReflectionType *)mono_array_get (types, gpointer, i);
-               type_argv [i] = mono_reflection_type_get_handle (garg, error);
-               if (!is_ok (error)) {
-                       g_free (type_argv);
-                       return NULL;
-               }
-       }
-       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.method_inst = ginst;
-
-       inflated = mono_class_inflate_generic_method_checked (method, &tmp_context, error);
-       mono_error_assert_ok (error);
-       imethod = (MonoMethodInflated *) inflated;
-
-       /*FIXME but I think this is no longer necessary*/
-       if (image_is_dynamic (method->klass->image)) {
-               MonoDynamicImage *image = (MonoDynamicImage*)method->klass->image;
-               /*
-                * This table maps metadata structures representing inflated methods/fields
-                * to the reflection objects representing their generic definitions.
-                */
-               mono_image_lock ((MonoImage*)image);
-               mono_g_hash_table_insert (image->generic_def_objects, imethod, rmethod);
-               mono_image_unlock ((MonoImage*)image);
-       }
-
-       if (!mono_verifier_is_method_valid_generic_instantiation (inflated)) {
-               mono_error_set_argument (error, "typeArguments", "Invalid generic arguments");
-               return NULL;
-       }
-       
-       MonoReflectionMethod *ret = mono_method_get_object_checked (mono_object_domain (rmethod), inflated, NULL, error);
-       return ret;
-}
-
-MonoReflectionMethod*
-ves_icall_MethodBuilder_MakeGenericMethod (MonoReflectionMethod *rmethod, MonoArray *types)
-{
-       MonoError error;
-       MonoReflectionMethod *result = reflection_bind_generic_method_parameters (rmethod, types, &error);
-       mono_error_set_pending_exception (&error);
-       return result;
-}
-
-MonoReflectionMethod*
-ves_icall_MonoMethod_MakeGenericMethod_impl (MonoReflectionMethod *rmethod, MonoArray *types)
-{
-       MonoError error;
-       MonoReflectionMethod *result = reflection_bind_generic_method_parameters (rmethod, types, &error);
-       mono_error_set_pending_exception (&error);
-       return result;
-}
-
-#ifndef DISABLE_REFLECTION_EMIT
-
-static MonoMethod *
-inflate_mono_method (MonoClass *klass, MonoMethod *method, MonoObject *obj)
-{
-       MonoMethodInflated *imethod;
-       MonoGenericContext *context;
-       int i;
-
-       /*
-        * With generic code sharing the klass might not be inflated.
-        * This can happen because classes inflated with their own
-        * type arguments are "normalized" to the uninflated class.
-        */
-       if (!klass->generic_class)
-               return method;
-
-       context = mono_class_get_context (klass);
-
-       if (klass->method.count && klass->methods) {
-               /* Find the already created inflated method */
-               for (i = 0; i < klass->method.count; ++i) {
-                       g_assert (klass->methods [i]->is_inflated);
-                       if (((MonoMethodInflated*)klass->methods [i])->declaring == method)
-                               break;
-               }
-               g_assert (i < klass->method.count);
-               imethod = (MonoMethodInflated*)klass->methods [i];
-       } else {
-               MonoError error;
-               imethod = (MonoMethodInflated *) mono_class_inflate_generic_method_full_checked (method, klass, context, &error);
-               mono_error_assert_ok (&error);
-       }
-
-       if (method->is_generic && image_is_dynamic (method->klass->image)) {
-               MonoDynamicImage *image = (MonoDynamicImage*)method->klass->image;
-
-               mono_image_lock ((MonoImage*)image);
-               mono_g_hash_table_insert (image->generic_def_objects, imethod, obj);
-               mono_image_unlock ((MonoImage*)image);
-       }
-       return (MonoMethod *) imethod;
-}
-
-static MonoMethod *
-inflate_method (MonoReflectionType *type, MonoObject *obj, MonoError *error)
-{
-       MonoMethod *method;
-       MonoClass *gklass;
-
-       mono_error_init (error);
-
-       MonoClass *type_class = mono_object_class (type);
-
-       if (is_sre_generic_instance (type_class)) {
-               MonoReflectionGenericClass *mgc = (MonoReflectionGenericClass*)type;
-               MonoType *generic_type = mono_reflection_type_get_handle ((MonoReflectionType*)mgc->generic_type, error);
-               return_val_if_nok (error, NULL);
-               gklass = mono_class_from_mono_type (generic_type);
-       } else if (is_sre_type_builder (type_class)) {
-               MonoType *t = mono_reflection_type_get_handle (type, error);
-               return_val_if_nok (error, NULL);
-               gklass = mono_class_from_mono_type (t);
-       } else if (type->type) {
-               gklass = mono_class_from_mono_type (type->type);
-               gklass = mono_class_get_generic_type_definition (gklass);
-       } else {
-               g_error ("Can't handle type %s", mono_type_get_full_name (mono_object_class (type)));
-       }
-
-       if (!strcmp (obj->vtable->klass->name, "MethodBuilder"))
-               if (((MonoReflectionMethodBuilder*)obj)->mhandle)
-                       method = ((MonoReflectionMethodBuilder*)obj)->mhandle;
-               else {
-                       method = methodbuilder_to_mono_method (gklass, (MonoReflectionMethodBuilder *) obj, error);
-                       if (!method)
-                               return NULL;
-               }
-       else if (!strcmp (obj->vtable->klass->name, "ConstructorBuilder")) {
-               method = ctorbuilder_to_mono_method (gklass, (MonoReflectionCtorBuilder *) obj, error);
-               if (!method)
-                       return NULL;
-       } else if (!strcmp (obj->vtable->klass->name, "MonoMethod") || !strcmp (obj->vtable->klass->name, "MonoCMethod"))
-               method = ((MonoReflectionMethod *) obj)->method;
-       else {
-               method = NULL; /* prevent compiler warning */
-               g_error ("can't handle type %s", obj->vtable->klass->name);
-       }
-
-       MonoType *t = mono_reflection_type_get_handle (type, error);
-       return_val_if_nok (error, NULL);
-       return inflate_mono_method (mono_class_from_mono_type (t), method, obj);
-}
-
-/*TODO avoid saving custom attrs for generic classes as it's enough to have them on the generic type definition.*/
-static gboolean
-reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields, MonoError *error)
-{
-       MonoGenericClass *gclass;
-       MonoDynamicGenericClass *dgclass;
-       MonoClass *klass, *gklass;
-       MonoType *gtype;
-       int i;
-
-       mono_error_init (error);
-
-       gtype = mono_reflection_type_get_handle ((MonoReflectionType*)type, error);
-       return_val_if_nok (error, FALSE);
-       klass = mono_class_from_mono_type (gtype);
-       g_assert (gtype->type == MONO_TYPE_GENERICINST);
-       gclass = gtype->data.generic_class;
-
-       if (!gclass->is_dynamic)
-               return TRUE;
-
-       dgclass = (MonoDynamicGenericClass *) gclass;
-
-       if (dgclass->initialized)
-               return TRUE;
-
-       gklass = gclass->container_class;
-       mono_class_init (gklass);
-
-       dgclass->count_fields = fields ? mono_array_length (fields) : 0;
-
-       dgclass->fields = mono_image_set_new0 (gclass->owner, MonoClassField, dgclass->count_fields);
-       dgclass->field_objects = mono_image_set_new0 (gclass->owner, MonoObject*, dgclass->count_fields);
-       dgclass->field_generic_types = mono_image_set_new0 (gclass->owner, MonoType*, dgclass->count_fields);
-
-       for (i = 0; i < dgclass->count_fields; i++) {
-               MonoObject *obj = (MonoObject *)mono_array_get (fields, gpointer, i);
-               MonoClassField *field, *inflated_field = NULL;
-
-               if (!strcmp (obj->vtable->klass->name, "FieldBuilder")) {
-                       inflated_field = field = fieldbuilder_to_mono_class_field (klass, (MonoReflectionFieldBuilder *) obj, error);
-                       return_val_if_nok (error, FALSE);
-               } else if (!strcmp (obj->vtable->klass->name, "MonoField"))
-                       field = ((MonoReflectionField *) obj)->field;
-               else {
-                       field = NULL; /* prevent compiler warning */
-                       g_assert_not_reached ();
-               }
-
-               dgclass->fields [i] = *field;
-               dgclass->fields [i].parent = klass;
-               dgclass->fields [i].type = mono_class_inflate_generic_type_checked (
-                       field->type, mono_generic_class_get_context ((MonoGenericClass *) dgclass), error);
-               mono_error_assert_ok (error); /* FIXME don't swallow the error */
-               dgclass->field_generic_types [i] = field->type;
-               MONO_GC_REGISTER_ROOT_IF_MOVING (dgclass->field_objects [i], MONO_ROOT_SOURCE_REFLECTION, "dynamic generic class field object");
-               dgclass->field_objects [i] = obj;
-
-               if (inflated_field) {
-                       g_free (inflated_field);
-               } else {
-                       dgclass->fields [i].name = mono_image_set_strdup (gclass->owner, dgclass->fields [i].name);
-               }
-       }
-
-       dgclass->initialized = TRUE;
-       return TRUE;
-}
-
-void
-mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields)
-{
-       MonoError error;
-       (void) reflection_generic_class_initialize (type, fields, &error);
-       mono_error_set_pending_exception (&error);
-}
-
-void
-mono_reflection_free_dynamic_generic_class (MonoGenericClass *gclass)
-{
-       MonoDynamicGenericClass *dgclass;
-       int i;
-
-       g_assert (gclass->is_dynamic);
-
-       dgclass = (MonoDynamicGenericClass *)gclass;
-
-       for (i = 0; i < dgclass->count_fields; ++i) {
-               MonoClassField *field = dgclass->fields + i;
-               mono_metadata_free_type (field->type);
-               MONO_GC_UNREGISTER_ROOT_IF_MOVING (dgclass->field_objects [i]);
+       assembly->name = p;
+       while (*p && (isalnum (*p) || *p == '.' || *p == '-' || *p == '_' || *p == '$' || *p == '@' || g_ascii_isspace (*p)))
+               p++;
+       if (quoted) {
+               if (*p != '"')
+                       return 1;
+               *p = 0;
+               p++;
        }
-}
-
-/**
- * fix_partial_generic_class:
- * @klass: a generic instantiation MonoClass
- * @error: set on error
- *
- * Assumes that the generic container of @klass has its vtable
- * initialized, and updates the parent class, insterfaces, methods and
- * fields of @klass by inflating the types using the generic context.
- *
- * On success returns TRUE, on failure returns FALSE and sets @error.
- *
- */
-static gboolean
-fix_partial_generic_class (MonoClass *klass, MonoError *error)
-{
-       MonoClass *gklass = klass->generic_class->container_class;
-       MonoDynamicGenericClass *dgclass;
-       int i;
-
-       mono_error_init (error);
-
-       if (klass->wastypebuilder)
-               return TRUE;
-
-       dgclass = (MonoDynamicGenericClass *)  klass->generic_class;
-       if (klass->parent != gklass->parent) {
-               MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &klass->generic_class->context, error);
-               if (mono_error_ok (error)) {
-                       MonoClass *parent = mono_class_from_mono_type (parent_type);
-                       mono_metadata_free_type (parent_type);
-                       if (parent != klass->parent) {
-                               /*fool mono_class_setup_parent*/
-                               klass->supertypes = NULL;
-                               mono_class_setup_parent (klass, parent);
+       if (*p != ',')
+               return 1;
+       *p = 0;
+       /* Remove trailing whitespace */
+       s = p - 1;
+       while (*s && g_ascii_isspace (*s))
+               *s-- = 0;
+       p ++;
+       while (g_ascii_isspace (*p))
+               p++;
+       while (*p) {
+               if (*p == 'V' && g_ascii_strncasecmp (p, "Version=", 8) == 0) {
+                       p += 8;
+                       assembly->major = strtoul (p, &s, 10);
+                       if (s == p || *s != '.')
+                               return 1;
+                       p = ++s;
+                       assembly->minor = strtoul (p, &s, 10);
+                       if (s == p || *s != '.')
+                               return 1;
+                       p = ++s;
+                       assembly->build = strtoul (p, &s, 10);
+                       if (s == p || *s != '.')
+                               return 1;
+                       p = ++s;
+                       assembly->revision = strtoul (p, &s, 10);
+                       if (s == p)
+                               return 1;
+                       p = s;
+               } else if (*p == 'C' && g_ascii_strncasecmp (p, "Culture=", 8) == 0) {
+                       p += 8;
+                       if (g_ascii_strncasecmp (p, "neutral", 7) == 0) {
+                               assembly->culture = "";
+                               p += 7;
+                       } else {
+                               assembly->culture = p;
+                               while (*p && *p != ',') {
+                                       p++;
+                               }
+                       }
+               } else if (*p == 'P' && g_ascii_strncasecmp (p, "PublicKeyToken=", 15) == 0) {
+                       p += 15;
+                       if (strncmp (p, "null", 4) == 0) {
+                               p += 4;
+                       } else {
+                               int len;
+                               gchar *start = p;
+                               while (*p && *p != ',') {
+                                       p++;
+                               }
+                               len = (p - start + 1);
+                               if (len > MONO_PUBLIC_KEY_TOKEN_LENGTH)
+                                       len = MONO_PUBLIC_KEY_TOKEN_LENGTH;
+                               g_strlcpy ((char*)assembly->public_key_token, start, len);
                        }
                } else {
-                       if (gklass->wastypebuilder)
-                               klass->wastypebuilder = TRUE;
-                       return FALSE;
-               }
-       }
-
-       if (!dgclass->initialized)
-               return TRUE;
-
-       if (klass->method.count != gklass->method.count) {
-               klass->method.count = gklass->method.count;
-               klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * (klass->method.count + 1));
-
-               for (i = 0; i < klass->method.count; i++) {
-                       klass->methods [i] = mono_class_inflate_generic_method_full_checked (
-                               gklass->methods [i], klass, mono_class_get_context (klass), error);
-                       mono_error_assert_ok (error);
-               }
-       }
-
-       if (klass->interface_count && klass->interface_count != gklass->interface_count) {
-               klass->interface_count = gklass->interface_count;
-               klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * gklass->interface_count);
-               klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
-
-               for (i = 0; i < gklass->interface_count; ++i) {
-                       MonoType *iface_type = mono_class_inflate_generic_type_checked (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass), error);
-                       return_val_if_nok (error, FALSE);
-
-                       klass->interfaces [i] = mono_class_from_mono_type (iface_type);
-                       mono_metadata_free_type (iface_type);
-
-                       if (!ensure_runtime_vtable (klass->interfaces [i], error))
-                               return FALSE;
+                       while (*p && *p != ',')
+                               p++;
                }
-               klass->interfaces_inited = 1;
-       }
-
-       if (klass->field.count != gklass->field.count) {
-               klass->field.count = gklass->field.count;
-               klass->fields = image_g_new0 (klass->image, MonoClassField, klass->field.count);
-
-               for (i = 0; i < klass->field.count; i++) {
-                       klass->fields [i] = gklass->fields [i];
-                       klass->fields [i].parent = klass;
-                       klass->fields [i].type = mono_class_inflate_generic_type_checked (gklass->fields [i].type, mono_class_get_context (klass), error);
-                       return_val_if_nok (error, FALSE);
+               found_sep = 0;
+               while (g_ascii_isspace (*p) || *p == ',') {
+                       *p++ = 0;
+                       found_sep = 1;
+                       continue;
                }
+               /* failed */
+               if (!found_sep)
+                       return 1;
        }
 
-       /*We can only finish with this klass once it's parent has as well*/
-       if (gklass->wastypebuilder)
-               klass->wastypebuilder = TRUE;
-       return TRUE;
+       return 0;
 }
 
-/**
- * ensure_generic_class_runtime_vtable:
- * @klass a generic class
- * @error set on error
+/*
+ * mono_reflection_parse_type:
+ * @name: type name
  *
- * Ensures that the generic container of @klass has a vtable and
- * returns TRUE on success.  On error returns FALSE and sets @error.
- */
-static gboolean
-ensure_generic_class_runtime_vtable (MonoClass *klass, MonoError *error)
-{
-       MonoClass *gklass = klass->generic_class->container_class;
-
-       mono_error_init (error);
-
-       if (!ensure_runtime_vtable (gklass, error))
-               return FALSE;
-
-       return fix_partial_generic_class (klass, error);
-}
-
-/**
- * ensure_runtime_vtable:
- * @klass the class
- * @error set on error
+ * Parse a type name as accepted by the GetType () method and output the info
+ * extracted in the info structure.
+ * the name param will be mangled, so, make a copy before passing it to this function.
+ * The fields in info will be valid until the memory pointed to by name is valid.
+ *
+ * See also mono_type_get_name () below.
  *
- * Ensures that @klass has a vtable and returns TRUE on success. On
- * error returns FALSE and sets @error.
+ * Returns: 0 on parse error.
  */
-static gboolean
-ensure_runtime_vtable (MonoClass *klass, MonoError *error)
-{
-       MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
-       int i, num, j;
-
-       mono_error_init (error);
-
-       if (!image_is_dynamic (klass->image) || (!tb && !klass->generic_class) || klass->wastypebuilder)
-               return TRUE;
-       if (klass->parent)
-               if (!ensure_runtime_vtable (klass->parent, error))
-                       return FALSE;
-
-       if (tb) {
-               num = tb->ctors? mono_array_length (tb->ctors): 0;
-               num += tb->num_methods;
-               klass->method.count = num;
-               klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * num);
-               num = tb->ctors? mono_array_length (tb->ctors): 0;
-               for (i = 0; i < num; ++i) {
-                       MonoMethod *ctor = ctorbuilder_to_mono_method (klass, mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i), error);
-                       if (!ctor)
-                               return FALSE;
-                       klass->methods [i] = ctor;
-               }
-               num = tb->num_methods;
-               j = i;
-               for (i = 0; i < num; ++i) {
-                       MonoMethod *meth = methodbuilder_to_mono_method (klass, mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), error);
-                       if (!meth)
-                               return FALSE;
-                       klass->methods [j++] = meth;
-               }
-       
-               if (tb->interfaces) {
-                       klass->interface_count = mono_array_length (tb->interfaces);
-                       klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
-                       for (i = 0; i < klass->interface_count; ++i) {
-                               MonoType *iface = mono_type_array_get_and_resolve (tb->interfaces, i, error);
-                               return_val_if_nok (error, FALSE);
-                               klass->interfaces [i] = mono_class_from_mono_type (iface);
-                               if (!ensure_runtime_vtable (klass->interfaces [i], error))
-                                       return FALSE;
-                       }
-                       klass->interfaces_inited = 1;
-               }
-       } else if (klass->generic_class){
-               if (!ensure_generic_class_runtime_vtable (klass, error)) {
-                       mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
-                       return FALSE;
-               }
-       }
-
-       if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
-               int slot_num = 0;
-               for (i = 0; i < klass->method.count; ++i) {
-                       MonoMethod *im = klass->methods [i];
-                       if (!(im->flags & METHOD_ATTRIBUTE_STATIC))
-                               im->slot = slot_num++;
-               }
-               
-               klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
-               mono_class_setup_interface_offsets (klass);
-               mono_class_setup_interface_id (klass);
-       }
-
-       /*
-        * The generic vtable is needed even if image->run is not set since some
-        * runtime code like ves_icall_Type_GetMethodsByName depends on 
-        * method->slot being defined.
-        */
-
-       /* 
-        * tb->methods could not be freed since it is used for determining 
-        * overrides during dynamic vtable construction.
-        */
-
-       return TRUE;
-}
-
-static MonoMethod*
-mono_reflection_method_get_handle (MonoObject *method, MonoError *error)
-{
-       mono_error_init (error);
-       MonoClass *klass = mono_object_class (method);
-       if (is_sr_mono_method (klass) || is_sr_mono_generic_method (klass)) {
-               MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
-               return sr_method->method;
-       }
-       if (is_sre_method_builder (klass)) {
-               MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)method;
-               return mb->mhandle;
-       }
-       if (is_sre_method_on_tb_inst (klass)) {
-               MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)method;
-               MonoMethod *result;
-               /*FIXME move this to a proper method and unify with resolve_object*/
-               if (m->method_args) {
-                       result = mono_reflection_method_on_tb_inst_get_handle (m, error);
-               } else {
-                       MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
-                       return_val_if_nok (error, NULL);
-                       MonoClass *inflated_klass = mono_class_from_mono_type (type);
-                       MonoMethod *mono_method;
-
-                       if (is_sre_method_builder (mono_object_class (m->mb)))
-                               mono_method = ((MonoReflectionMethodBuilder *)m->mb)->mhandle;
-                       else if (is_sr_mono_method (mono_object_class (m->mb)))
-                               mono_method = ((MonoReflectionMethod *)m->mb)->method;
-                       else
-                               g_error ("resolve_object:: can't handle a MTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (m->mb)));
-
-                       result = inflate_mono_method (inflated_klass, mono_method, (MonoObject*)m->mb);
-               }
-               return result;
-       }
-
-       g_error ("Can't handle methods of type %s:%s", klass->name_space, klass->name);
-       return NULL;
-}
-
-void
-mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
+static int
+_mono_reflection_parse_type (char *name, char **endptr, gboolean is_recursed,
+                            MonoTypeNameParse *info)
 {
-       MonoReflectionTypeBuilder *tb;
-       int i, j, onum;
-       MonoReflectionMethod *m;
-
-       mono_error_init (error);
-       *overrides = NULL;
-       *num_overrides = 0;
-
-       g_assert (image_is_dynamic (klass->image));
-
-       if (!mono_class_get_ref_info (klass))
-               return;
-
-       g_assert (strcmp (((MonoObject*)mono_class_get_ref_info (klass))->vtable->klass->name, "TypeBuilder") == 0);
-
-       tb = (MonoReflectionTypeBuilder*)mono_class_get_ref_info (klass);
-
-       onum = 0;
-       if (tb->methods) {
-               for (i = 0; i < tb->num_methods; ++i) {
-                       MonoReflectionMethodBuilder *mb = 
-                               mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
-                       if (mb->override_methods)
-                               onum += mono_array_length (mb->override_methods);
-               }
-       }
-
-       if (onum) {
-               *overrides = g_new0 (MonoMethod*, onum * 2);
+       char *start, *p, *w, *last_point, *startn;
+       int in_modifiers = 0;
+       int isbyref = 0, rank = 0, isptr = 0;
 
-               onum = 0;
-               for (i = 0; i < tb->num_methods; ++i) {
-                       MonoReflectionMethodBuilder *mb = 
-                               mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
-                       if (mb->override_methods) {
-                               for (j = 0; j < mono_array_length (mb->override_methods); ++j) {
-                                       m = mono_array_get (mb->override_methods, MonoReflectionMethod*, j);
+       start = p = w = name;
 
-                                       (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject*)m, error);
-                                       return_if_nok (error);
-                                       (*overrides) [onum * 2 + 1] = mb->mhandle;
+       //FIXME could we just zero the whole struct? memset (&info, 0, sizeof (MonoTypeNameParse))
+       memset (&info->assembly, 0, sizeof (MonoAssemblyName));
+       info->name = info->name_space = NULL;
+       info->nested = NULL;
+       info->modifiers = NULL;
+       info->type_arguments = NULL;
 
-                                       g_assert (mb->mhandle);
+       /* last_point separates the namespace from the name */
+       last_point = NULL;
+       /* Skips spaces */
+       while (*p == ' ') p++, start++, w++, name++;
 
-                                       onum ++;
-                               }
+       while (*p) {
+               switch (*p) {
+               case '+':
+                       *p = 0; /* NULL terminate the name */
+                       startn = p + 1;
+                       info->nested = g_list_append (info->nested, startn);
+                       /* we have parsed the nesting namespace + name */
+                       if (info->name)
+                               break;
+                       if (last_point) {
+                               info->name_space = start;
+                               *last_point = 0;
+                               info->name = last_point + 1;
+                       } else {
+                               info->name_space = (char *)"";
+                               info->name = start;
                        }
+                       break;
+               case '.':
+                       last_point = p;
+                       break;
+               case '\\':
+                       ++p;
+                       break;
+               case '&':
+               case '*':
+               case '[':
+               case ',':
+               case ']':
+                       in_modifiers = 1;
+                       break;
+               default:
+                       break;
                }
-       }
-
-       *num_overrides = onum;
-}
-
-static void
-typebuilder_setup_fields (MonoClass *klass, MonoError *error)
-{
-       MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
-       MonoReflectionFieldBuilder *fb;
-       MonoClassField *field;
-       MonoImage *image = klass->image;
-       const char *p, *p2;
-       int i;
-       guint32 len, idx, real_size = 0;
-
-       klass->field.count = tb->num_fields;
-       klass->field.first = 0;
-
-       mono_error_init (error);
-
-       if (tb->class_size) {
-               if ((tb->packing_size & 0xffffff00) != 0) {
-                       char *err_msg = g_strdup_printf ("Could not load struct '%s' with packing size %d >= 256", klass->name, tb->packing_size);
-                       mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
-                       return;
-               }
-               klass->packing_size = tb->packing_size;
-               real_size = klass->instance_size + tb->class_size;
-       }
-
-       if (!klass->field.count) {
-               klass->instance_size = MAX (klass->instance_size, real_size);
-               return;
+               if (in_modifiers)
+                       break;
+               // *w++ = *p++;
+               p++;
        }
        
-       klass->fields = image_g_new0 (image, MonoClassField, klass->field.count);
-       mono_class_alloc_ext (klass);
-       klass->ext->field_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->field.count);
-       /*
-       This is, guess what, a hack.
-       The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
-       On the static path no field class is resolved, only types are built. This is the right thing to do
-       but we suck.
-       Setting size_inited is harmless because we're doing the same job as mono_class_setup_fields anyway.
-       */
-       klass->size_inited = 1;
-
-       for (i = 0; i < klass->field.count; ++i) {
-               MonoArray *rva_data;
-               fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
-               field = &klass->fields [i];
-               field->name = mono_string_to_utf8_image (image, fb->name, error);
-               if (!mono_error_ok (error))
-                       return;
-               if (fb->attrs) {
-                       MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
-                       return_if_nok (error);
-                       field->type = mono_metadata_type_dup (klass->image, type);
-                       field->type->attrs = fb->attrs;
+       if (!info->name) {
+               if (last_point) {
+                       info->name_space = start;
+                       *last_point = 0;
+                       info->name = last_point + 1;
                } else {
-                       field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
-                       return_if_nok (error);
-               }
-
-               if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
-                       char *base = mono_array_addr (rva_data, char, 0);
-                       size_t size = mono_array_length (rva_data);
-                       char *data = (char *)mono_image_alloc (klass->image, size);
-                       memcpy (data, base, size);
-                       klass->ext->field_def_values [i].data = data;
-               }
-               if (fb->offset != -1)
-                       field->offset = fb->offset;
-               field->parent = klass;
-               fb->handle = field;
-               mono_save_custom_attrs (klass->image, field, fb->cattrs);
-
-               if (klass->enumtype && !(field->type->attrs & FIELD_ATTRIBUTE_STATIC)) {
-                       klass->cast_class = klass->element_class = mono_class_from_mono_type (field->type);
-               }
-               if (fb->def_value) {
-                       MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
-                       field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
-                       idx = encode_constant (assembly, fb->def_value, &klass->ext->field_def_values [i].def_type);
-                       /* Copy the data from the blob since it might get realloc-ed */
-                       p = assembly->blob.data + idx;
-                       len = mono_metadata_decode_blob_size (p, &p2);
-                       len += p2 - p;
-                       klass->ext->field_def_values [i].data = (const char *)mono_image_alloc (image, len);
-                       memcpy ((gpointer)klass->ext->field_def_values [i].data, p, len);
+                       info->name_space = (char *)"";
+                       info->name = start;
                }
        }
+       while (*p) {
+               switch (*p) {
+               case '&':
+                       if (isbyref) /* only one level allowed by the spec */
+                               return 0;
+                       isbyref = 1;
+                       isptr = 0;
+                       info->modifiers = g_list_append (info->modifiers, GUINT_TO_POINTER (0));
+                       *p++ = 0;
+                       break;
+               case '*':
+                       if (isbyref) /* pointer to ref not okay */
+                               return 0;
+                       info->modifiers = g_list_append (info->modifiers, GUINT_TO_POINTER (-1));
+                       isptr = 1;
+                       *p++ = 0;
+                       break;
+               case '[':
+                       if (isbyref) /* array of ref and generic ref are not okay */
+                               return 0;
+                       //Decide if it's an array of a generic argument list
+                       *p++ = 0;
 
-       klass->instance_size = MAX (klass->instance_size, real_size);
-       mono_class_layout_fields (klass, klass->instance_size);
-}
-
-static void
-typebuilder_setup_properties (MonoClass *klass, MonoError *error)
-{
-       MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
-       MonoReflectionPropertyBuilder *pb;
-       MonoImage *image = klass->image;
-       MonoProperty *properties;
-       int i;
+                       if (!*p) //XXX test
+                               return 0;
+                       if (*p  == ',' || *p == '*' || *p == ']') { //array
+                               isptr = 0;
+                               rank = 1;
+                               while (*p) {
+                                       if (*p == ']')
+                                               break;
+                                       if (*p == ',')
+                                               rank++;
+                                       else if (*p == '*') /* '*' means unknown lower bound */
+                                               info->modifiers = g_list_append (info->modifiers, GUINT_TO_POINTER (-2));
+                                       else
+                                               return 0;
+                                       ++p;
+                               }
+                               if (*p++ != ']')
+                                       return 0;
+                               info->modifiers = g_list_append (info->modifiers, GUINT_TO_POINTER (rank));
+                       } else {
+                               if (rank || isptr) /* generic args after array spec or ptr*/ //XXX test
+                                       return 0;
+                               isptr = 0;
+                               info->type_arguments = g_ptr_array_new ();
+                               while (*p) {
+                                       MonoTypeNameParse *subinfo = g_new0 (MonoTypeNameParse, 1);
+                                       gboolean fqname = FALSE;
 
-       mono_error_init (error);
+                                       g_ptr_array_add (info->type_arguments, subinfo);
 
-       if (!klass->ext)
-               klass->ext = image_g_new0 (image, MonoClassExt, 1);
+                                       while (*p == ' ') p++;
+                                       if (*p == '[') {
+                                               p++;
+                                               fqname = TRUE;
+                                       }
 
-       klass->ext->property.count = tb->properties ? mono_array_length (tb->properties) : 0;
-       klass->ext->property.first = 0;
+                                       if (!_mono_reflection_parse_type (p, &p, TRUE, subinfo))
+                                               return 0;
 
-       properties = image_g_new0 (image, MonoProperty, klass->ext->property.count);
-       klass->ext->properties = properties;
-       for (i = 0; i < klass->ext->property.count; ++i) {
-               pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
-               properties [i].parent = klass;
-               properties [i].attrs = pb->attrs;
-               properties [i].name = mono_string_to_utf8_image (image, pb->name, error);
-               if (!mono_error_ok (error))
-                       return;
-               if (pb->get_method)
-                       properties [i].get = pb->get_method->mhandle;
-               if (pb->set_method)
-                       properties [i].set = pb->set_method->mhandle;
-
-               mono_save_custom_attrs (klass->image, &properties [i], pb->cattrs);
-               if (pb->def_value) {
-                       guint32 len, idx;
-                       const char *p, *p2;
-                       MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
-                       if (!klass->ext->prop_def_values)
-                               klass->ext->prop_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->ext->property.count);
-                       properties [i].attrs |= PROPERTY_ATTRIBUTE_HAS_DEFAULT;
-                       idx = encode_constant (assembly, pb->def_value, &klass->ext->prop_def_values [i].def_type);
-                       /* Copy the data from the blob since it might get realloc-ed */
-                       p = assembly->blob.data + idx;
-                       len = mono_metadata_decode_blob_size (p, &p2);
-                       len += p2 - p;
-                       klass->ext->prop_def_values [i].data = (const char *)mono_image_alloc (image, len);
-                       memcpy ((gpointer)klass->ext->prop_def_values [i].data, p, len);
-               }
-       }
-}
+                                       /*MS is lenient on [] delimited parameters that aren't fqn - and F# uses them.*/
+                                       if (fqname && (*p != ']')) {
+                                               char *aname;
 
-static MonoReflectionEvent *
-reflection_event_builder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb, MonoError *error)
-{
-       mono_error_init (error);
+                                               if (*p != ',')
+                                                       return 0;
+                                               *p++ = 0;
 
-       MonoEvent *event = g_new0 (MonoEvent, 1);
-       MonoClass *klass;
+                                               aname = p;
+                                               while (*p && (*p != ']'))
+                                                       p++;
 
-       MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
-       if (!is_ok (error)) {
-               g_free (event);
-               return NULL;
-       }
-       klass = mono_class_from_mono_type (type);
+                                               if (*p != ']')
+                                                       return 0;
 
-       event->parent = klass;
-       event->attrs = eb->attrs;
-       event->name = mono_string_to_utf8_checked (eb->name, error);
-       if (!is_ok (error)) {
-               g_free (event);
-               return NULL;
-       }
-       if (eb->add_method)
-               event->add = eb->add_method->mhandle;
-       if (eb->remove_method)
-               event->remove = eb->remove_method->mhandle;
-       if (eb->raise_method)
-               event->raise = eb->raise_method->mhandle;
-
-#ifndef MONO_SMALL_CONFIG
-       if (eb->other_methods) {
-               int j;
-               event->other = g_new0 (MonoMethod*, mono_array_length (eb->other_methods) + 1);
-               for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
-                       MonoReflectionMethodBuilder *mb = 
-                               mono_array_get (eb->other_methods,
-                                               MonoReflectionMethodBuilder*, j);
-                       event->other [j] = mb->mhandle;
+                                               *p++ = 0;
+                                               while (*aname) {
+                                                       if (g_ascii_isspace (*aname)) {
+                                                               ++aname;
+                                                               continue;
+                                                       }
+                                                       break;
+                                               }
+                                               if (!*aname ||
+                                                   !assembly_name_to_aname (&subinfo->assembly, aname))
+                                                       return 0;
+                                       } else if (fqname && (*p == ']')) {
+                                               *p++ = 0;
+                                       }
+                                       if (*p == ']') {
+                                               *p++ = 0;
+                                               break;
+                                       } else if (!*p) {
+                                               return 0;
+                                       }
+                                       *p++ = 0;
+                               }
+                       }
+                       break;
+               case ']':
+                       if (is_recursed)
+                               goto end;
+                       return 0;
+               case ',':
+                       if (is_recursed)
+                               goto end;
+                       *p++ = 0;
+                       while (*p) {
+                               if (g_ascii_isspace (*p)) {
+                                       ++p;
+                                       continue;
+                               }
+                               break;
+                       }
+                       if (!*p)
+                               return 0; /* missing assembly name */
+                       if (!assembly_name_to_aname (&info->assembly, p))
+                               return 0;
+                       break;
+               default:
+                       return 0;
                }
+               if (info->assembly.name)
+                       break;
        }
-#endif
-
-       MonoReflectionEvent *ev_obj = mono_event_get_object_checked (mono_object_domain (tb), klass, event, error);
-       if (!is_ok (error)) {
-#ifndef MONO_SMALL_CONFIG
-               g_free (event->other);
-#endif
-               g_free (event);
-               return NULL;
-       }
-       return ev_obj;
-}
-
-MonoReflectionEvent *
-ves_icall_TypeBuilder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb)
-{
-       MonoError error;
-       MonoReflectionEvent *result = reflection_event_builder_get_event_info (tb, eb, &error);
-       mono_error_set_pending_exception (&error);
-       return result;
+       // *w = 0; /* terminate class name */
+ end:
+       if (!info->name || !*info->name)
+               return 0;
+       if (endptr)
+               *endptr = p;
+       /* add other consistency checks */
+       return 1;
 }
 
-static void
-typebuilder_setup_events (MonoClass *klass, MonoError *error)
-{
-       MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
-       MonoReflectionEventBuilder *eb;
-       MonoImage *image = klass->image;
-       MonoEvent *events;
-       int i;
-
-       mono_error_init (error);
-
-       if (!klass->ext)
-               klass->ext = image_g_new0 (image, MonoClassExt, 1);
-
-       klass->ext->event.count = tb->events ? mono_array_length (tb->events) : 0;
-       klass->ext->event.first = 0;
 
-       events = image_g_new0 (image, MonoEvent, klass->ext->event.count);
-       klass->ext->events = events;
-       for (i = 0; i < klass->ext->event.count; ++i) {
-               eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
-               events [i].parent = klass;
-               events [i].attrs = eb->attrs;
-               events [i].name = mono_string_to_utf8_image (image, eb->name, error);
-               if (!mono_error_ok (error))
-                       return;
-               if (eb->add_method)
-                       events [i].add = eb->add_method->mhandle;
-               if (eb->remove_method)
-                       events [i].remove = eb->remove_method->mhandle;
-               if (eb->raise_method)
-                       events [i].raise = eb->raise_method->mhandle;
-
-#ifndef MONO_SMALL_CONFIG
-               if (eb->other_methods) {
-                       int j;
-                       events [i].other = image_g_new0 (image, MonoMethod*, mono_array_length (eb->other_methods) + 1);
-                       for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
-                               MonoReflectionMethodBuilder *mb = 
-                                       mono_array_get (eb->other_methods,
-                                                                       MonoReflectionMethodBuilder*, j);
-                               events [i].other [j] = mb->mhandle;
-                       }
+/**
+ * mono_identifier_unescape_type_name_chars:
+ * @identifier: the display name of a mono type
+ *
+ * Returns:
+ *  The name in internal form, that is without escaping backslashes.
+ *
+ *  The string is modified in place!
+ */
+char*
+mono_identifier_unescape_type_name_chars(char* identifier)
+{
+       char *w, *r;
+       if (!identifier)
+               return NULL;
+       for (w = r = identifier; *r != 0; r++)
+       {
+               char c = *r;
+               if (c == '\\') {
+                       r++;
+                       if (*r == 0)
+                               break;
+                       c = *r;
                }
-#endif
-               mono_save_custom_attrs (klass->image, &events [i], eb->cattrs);
+               *w = c;
+               w++;
        }
+       if (w != r)
+               *w = 0;
+       return identifier;
 }
 
-struct remove_instantiations_user_data
-{
-       MonoClass *klass;
-       MonoError *error;
-};
+void
+mono_identifier_unescape_info (MonoTypeNameParse* info);
 
-static gboolean
-remove_instantiations_of_and_ensure_contents (gpointer key,
-                                                 gpointer value,
-                                                 gpointer user_data)
+static void
+unescape_each_type_argument(void* data, void* user_data)
 {
-       struct remove_instantiations_user_data *data = (struct remove_instantiations_user_data*)user_data;
-       MonoType *type = (MonoType*)key;
-       MonoClass *klass = data->klass;
-       gboolean already_failed = !is_ok (data->error);
-       MonoError lerror;
-       MonoError *error = already_failed ? &lerror : data->error;
-
-       if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass)) {
-               MonoClass *inst_klass = mono_class_from_mono_type (type);
-               //Ensure it's safe to use it.
-               if (!fix_partial_generic_class (inst_klass, error)) {
-                       mono_class_set_failure (inst_klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
-                       // Marked the class with failure, but since some other instantiation already failed,
-                       // just report that one, and swallow the error from this one.
-                       if (already_failed)
-                               mono_error_cleanup (error);
-               }
-               return TRUE;
-       } else
-               return FALSE;
+       MonoTypeNameParse* info = (MonoTypeNameParse*)data;
+       mono_identifier_unescape_info (info);
 }
 
 static void
-check_array_for_usertypes (MonoArray *arr, MonoError *error)
+unescape_each_nested_name (void* data, void* user_data)
 {
-       mono_error_init (error);
-       int i;
+       char* nested_name = (char*) data;
+       mono_identifier_unescape_type_name_chars(nested_name);
+}
 
-       if (!arr)
+/**
+ * mono_identifier_unescape_info:
+ *
+ * @info: a parsed display form of an (optionally assembly qualified) full type name.
+ *
+ * Returns: nothing.
+ *
+ * Destructively updates the info by unescaping the identifiers that
+ * comprise the type namespace, name, nested types (if any) and
+ * generic type arguments (if any).
+ *
+ * The resulting info has the names in internal form.
+ *
+ */
+void
+mono_identifier_unescape_info (MonoTypeNameParse *info)
+{
+       if (!info)
                return;
+       mono_identifier_unescape_type_name_chars(info->name_space);
+       mono_identifier_unescape_type_name_chars(info->name);
+       // but don't escape info->assembly
+       if (info->type_arguments)
+               g_ptr_array_foreach(info->type_arguments, &unescape_each_type_argument, NULL);
+       if (info->nested)
+               g_list_foreach(info->nested, &unescape_each_nested_name, NULL);
+}
 
-       for (i = 0; i < mono_array_length (arr); ++i) {
-               RESOLVE_ARRAY_TYPE_ELEMENT (arr, i, error);
-               if (!mono_error_ok (error))
-                       break;
+int
+mono_reflection_parse_type (char *name, MonoTypeNameParse *info)
+{
+       int ok = _mono_reflection_parse_type (name, NULL, FALSE, info);
+       if (ok) {
+               mono_identifier_unescape_info (info);
        }
+       return ok;
 }
 
-MonoReflectionType*
-ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
+static MonoType*
+_mono_reflection_get_type_from_info (MonoTypeNameParse *info, MonoImage *image, gboolean ignorecase, MonoError *error)
 {
-       MonoError error;
-       MonoClass *klass;
-       MonoDomain* domain;
-       MonoReflectionType* res;
-       int i, j;
-
-       mono_error_init (&error);
+       gboolean type_resolve = FALSE;
+       MonoType *type;
+       MonoImage *rootimage = image;
 
-       domain = mono_object_domain (tb);
-       klass = mono_class_from_mono_type (tb->type.type);
+       mono_error_init (error);
 
-       /*
-        * Check for user defined Type subclasses.
-        */
-       RESOLVE_TYPE (tb->parent, &error);
-       if (!is_ok (&error))
-               goto failure_unlocked;
-       check_array_for_usertypes (tb->interfaces, &error);
-       if (!is_ok (&error))
-               goto failure_unlocked;
-       if (tb->fields) {
-               for (i = 0; i < mono_array_length (tb->fields); ++i) {
-                       MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
-                       if (fb) {
-                               RESOLVE_TYPE (fb->type, &error);
-                               if (!is_ok (&error))
-                                       goto failure_unlocked;
-                               check_array_for_usertypes (fb->modreq, &error);
-                               if (!is_ok (&error))
-                                       goto failure_unlocked;
-                               check_array_for_usertypes (fb->modopt, &error);
-                               if (!is_ok (&error))
-                                       goto failure_unlocked;
-                               if (fb->marshal_info && fb->marshal_info->marshaltyperef) {
-                                       RESOLVE_TYPE (fb->marshal_info->marshaltyperef, &error);
-                                       if (!is_ok (&error))
-                                               goto failure_unlocked;
-                               }
-                       }
-               }
-       }
-       if (tb->methods) {
-               for (i = 0; i < mono_array_length (tb->methods); ++i) {
-                       MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)mono_array_get (tb->methods, gpointer, i);
-                       if (mb) {
-                               RESOLVE_TYPE (mb->rtype, &error);
-                               if (!is_ok (&error))
-                                       goto failure_unlocked;
-                               check_array_for_usertypes (mb->return_modreq, &error);
-                               if (!is_ok (&error))
-                                       goto failure_unlocked;
-                               check_array_for_usertypes (mb->return_modopt, &error);
-                               if (!is_ok (&error))
-                                       goto failure_unlocked;
-                               check_array_for_usertypes (mb->parameters, &error);
-                               if (!is_ok (&error))
-                                       goto failure_unlocked;
-                               if (mb->param_modreq)
-                                       for (j = 0; j < mono_array_length (mb->param_modreq); ++j) {
-                                               check_array_for_usertypes (mono_array_get (mb->param_modreq, MonoArray*, j), &error);
-                                               if (!is_ok (&error))
-                                                       goto failure_unlocked;
-                                       }
-                               if (mb->param_modopt)
-                                       for (j = 0; j < mono_array_length (mb->param_modopt); ++j) {
-                                               check_array_for_usertypes (mono_array_get (mb->param_modopt, MonoArray*, j), &error);
-                                               if (!is_ok (&error))
-                                                       goto failure_unlocked;
-                                       }
-                       }
-               }
-       }
-       if (tb->ctors) {
-               for (i = 0; i < mono_array_length (tb->ctors); ++i) {
-                       MonoReflectionCtorBuilder *mb = (MonoReflectionCtorBuilder *)mono_array_get (tb->ctors, gpointer, i);
-                       if (mb) {
-                               check_array_for_usertypes (mb->parameters, &error);
-                               if (!is_ok (&error))
-                                       goto failure_unlocked;
-                               if (mb->param_modreq)
-                                       for (j = 0; j < mono_array_length (mb->param_modreq); ++j) {
-                                               check_array_for_usertypes (mono_array_get (mb->param_modreq, MonoArray*, j), &error);
-                                               if (!is_ok (&error))
-                                                       goto failure_unlocked;
-                                       }
-                               if (mb->param_modopt)
-                                       for (j = 0; j < mono_array_length (mb->param_modopt); ++j) {
-                                               check_array_for_usertypes (mono_array_get (mb->param_modopt, MonoArray*, j), &error);
-                                               if (!is_ok (&error))
-                                                       goto failure_unlocked;
-                                       }
-                       }
+       if (info->assembly.name) {
+               MonoAssembly *assembly = mono_assembly_loaded (&info->assembly);
+               if (!assembly && image && image->assembly && mono_assembly_names_equal (&info->assembly, &image->assembly->aname))
+                       /* 
+                        * This could happen in the AOT compiler case when the search hook is not
+                        * installed.
+                        */
+                       assembly = image->assembly;
+               if (!assembly) {
+                       /* then we must load the assembly ourselve - see #60439 */
+                       assembly = mono_assembly_load (&info->assembly, image->assembly->basedir, NULL);
+                       if (!assembly)
+                               return NULL;
                }
+               image = assembly->image;
+       } else if (!image) {
+               image = mono_defaults.corlib;
        }
 
-       mono_save_custom_attrs (klass->image, klass, tb->cattrs);
-
-       /* 
-        * we need to lock the domain because the lock will be taken inside
-        * So, we need to keep the locking order correct.
-        */
-       mono_loader_lock ();
-       mono_domain_lock (domain);
-       if (klass->wastypebuilder) {
-               mono_domain_unlock (domain);
-               mono_loader_unlock ();
-
-               res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
-               mono_error_set_pending_exception (&error);
-
-               return res;
+       type = mono_reflection_get_type_with_rootimage (rootimage, image, info, ignorecase, &type_resolve, error);
+       if (type == NULL && !info->assembly.name && image != mono_defaults.corlib) {
+               /* ignore the error and try again */
+               mono_error_cleanup (error);
+               mono_error_init (error);
+               image = mono_defaults.corlib;
+               type = mono_reflection_get_type_with_rootimage (rootimage, image, info, ignorecase, &type_resolve, error);
        }
-       /*
-        * Fields to set in klass:
-        * the various flags: delegate/unicode/contextbound etc.
-        */
-       klass->flags = tb->attrs;
-       klass->has_cctor = 1;
-
-       mono_class_setup_parent (klass, klass->parent);
-       /* fool mono_class_setup_supertypes */
-       klass->supertypes = NULL;
-       mono_class_setup_supertypes (klass);
-       mono_class_setup_mono_type (klass);
-
-#if 0
-       if (!((MonoDynamicImage*)klass->image)->run) {
-               if (klass->generic_container) {
-                       /* FIXME: The code below can't handle generic classes */
-                       klass->wastypebuilder = TRUE;
-                       mono_loader_unlock ();
-                       mono_domain_unlock (domain);
 
-                       res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
-                       mono_error_set_pending_exception (&error);
-
-                       return res;
-               }
-       }
-#endif
+       return type;
+}
 
-       /* enums are done right away */
-       if (!klass->enumtype)
-               if (!ensure_runtime_vtable (klass, &error))
-                       goto failure;
+/**
+ * mono_reflection_get_type_internal:
+ *
+ * Returns: may return NULL on success, sets error on failure.
+ */
+static MonoType*
+mono_reflection_get_type_internal (MonoImage *rootimage, MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, MonoError *error)
+{
+       MonoClass *klass;
+       GList *mod;
+       int modval;
+       gboolean bounded = FALSE;
+       
+       mono_error_init (error);
+       if (!image)
+               image = mono_defaults.corlib;
 
-       if (tb->subtypes) {
-               for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
-                       MonoReflectionTypeBuilder *subtb = mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i);
-                       mono_class_alloc_ext (klass);
-                       MonoType *subtype = mono_reflection_type_get_handle ((MonoReflectionType*)subtb, &error);
-                       if (!is_ok (&error)) goto failure;
-                       klass->ext->nested_classes = g_list_prepend_image (klass->image, klass->ext->nested_classes, mono_class_from_mono_type (subtype));
-               }
-       }
+       if (!rootimage)
+               rootimage = mono_defaults.corlib;
 
-       klass->nested_classes_inited = TRUE;
-
-       /* fields and object layout */
-       if (klass->parent) {
-               if (!klass->parent->size_inited)
-                       mono_class_init (klass->parent);
-               klass->instance_size = klass->parent->instance_size;
-               klass->sizes.class_size = 0;
-               klass->min_align = klass->parent->min_align;
-               /* if the type has no fields we won't call the field_setup
-                * routine which sets up klass->has_references.
-                */
-               klass->has_references |= klass->parent->has_references;
-       } else {
-               klass->instance_size = sizeof (MonoObject);
-               klass->min_align = 1;
-       }
+       if (ignorecase)
+               klass = mono_class_from_name_case_checked (image, info->name_space, info->name, error);
+       else
+               klass = mono_class_from_name_checked (image, info->name_space, info->name, error);
 
-       /* FIXME: handle packing_size and instance_size */
-       typebuilder_setup_fields (klass, &error);
-       if (!mono_error_ok (&error))
-               goto failure;
-       typebuilder_setup_properties (klass, &error);
-       if (!mono_error_ok (&error))
-               goto failure;
+       if (!klass)
+               return NULL;
 
-       typebuilder_setup_events (klass, &error);
-       if (!mono_error_ok (&error))
-               goto failure;
+       for (mod = info->nested; mod; mod = mod->next) {
+               gpointer iter = NULL;
+               MonoClass *parent;
 
-       klass->wastypebuilder = TRUE;
+               parent = klass;
+               mono_class_init (parent);
 
-       /* 
-        * If we are a generic TypeBuilder, there might be instantiations in the type cache
-        * which have type System.Reflection.MonoGenericClass, but after the type is created, 
-        * we want to return normal System.MonoType objects, so clear these out from the cache.
-        *
-        * Together with this we must ensure the contents of all instances to match the created type.
-        */
-       if (domain->type_hash && klass->generic_container) {
-               struct remove_instantiations_user_data data;
-               data.klass = klass;
-               data.error = &error;
-               mono_error_assert_ok (&error);
-               mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of_and_ensure_contents, &data);
-               if (!is_ok (&error))
-                       goto failure;
-       }
+               while ((klass = mono_class_get_nested_types (parent, &iter))) {
+                       char *lastp;
+                       char *nested_name, *nested_nspace;
+                       gboolean match = TRUE;
 
-       mono_domain_unlock (domain);
-       mono_loader_unlock ();
+                       lastp = strrchr ((const char *)mod->data, '.');
+                       if (lastp) {
+                               /* Nested classes can have namespaces */
+                               int nspace_len;
 
-       if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
-               mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
-               mono_error_set_type_load_class (&error, klass, "Not a valid enumeration");
-               goto failure_unlocked;
-       }
+                               nested_name = g_strdup (lastp + 1);
+                               nspace_len = lastp - (char*)mod->data;
+                               nested_nspace = (char *)g_malloc (nspace_len + 1);
+                               memcpy (nested_nspace, mod->data, nspace_len);
+                               nested_nspace [nspace_len] = '\0';
 
-       res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
-       if (!is_ok (&error))
-               goto failure_unlocked;
+                       } else {
+                               nested_name = (char *)mod->data;
+                               nested_nspace = NULL;
+                       }
 
-       g_assert (res != (MonoReflectionType*)tb);
+                       if (nested_nspace) {
+                               if (ignorecase) {
+                                       if (!(klass->name_space && mono_utf8_strcasecmp (klass->name_space, nested_nspace) == 0))
+                                               match = FALSE;
+                               } else {
+                                       if (!(klass->name_space && strcmp (klass->name_space, nested_nspace) == 0))
+                                               match = FALSE;
+                               }
+                       }
+                       if (match) {
+                               if (ignorecase) {
+                                       if (mono_utf8_strcasecmp (klass->name, nested_name) != 0)
+                                               match = FALSE;
+                               } else {
+                                       if (strcmp (klass->name, nested_name) != 0)
+                                               match = FALSE;
+                               }
+                       }
+                       if (lastp) {
+                               g_free (nested_name);
+                               g_free (nested_nspace);
+                       }
+                       if (match)
+                               break;
+               }
 
-       return res;
+               if (!klass)
+                       break;
+       }
+       if (!klass)
+               return NULL;
 
-failure:
-       mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
-       klass->wastypebuilder = TRUE;
-       mono_domain_unlock (domain);
-       mono_loader_unlock ();
-failure_unlocked:
-       mono_error_set_pending_exception (&error);
-       return NULL;
-}
+       if (info->type_arguments) {
+               MonoType **type_args = g_new0 (MonoType *, info->type_arguments->len);
+               MonoReflectionType *the_type;
+               MonoType *instance;
+               int i;
 
-static gboolean
-reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam, MonoError *error)
-{
-       MonoGenericParamFull *param;
-       MonoImage *image;
-       MonoClass *pklass;
+               for (i = 0; i < info->type_arguments->len; i++) {
+                       MonoTypeNameParse *subinfo = (MonoTypeNameParse *)g_ptr_array_index (info->type_arguments, i);
 
-       mono_error_init (error);
+                       type_args [i] = _mono_reflection_get_type_from_info (subinfo, rootimage, ignorecase, error);
+                       if (!type_args [i]) {
+                               g_free (type_args);
+                               return NULL;
+                       }
+               }
 
-       image = &gparam->tbuilder->module->dynamic_image->image;
+               the_type = mono_type_get_object_checked (mono_domain_get (), &klass->byval_arg, error);
+               if (!the_type)
+                       return NULL;
 
-       param = mono_image_new0 (image, MonoGenericParamFull, 1);
+               instance = mono_reflection_bind_generic_parameters (
+                       the_type, info->type_arguments->len, type_args, error);
 
-       param->info.name = mono_string_to_utf8_image (image, gparam->name, error);
-       mono_error_assert_ok (error);
-       param->param.num = gparam->index;
+               g_free (type_args);
+               if (!instance)
+                       return NULL;
 
-       if (gparam->mbuilder) {
-               if (!gparam->mbuilder->generic_container) {
-                       MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->mbuilder->type, error);
-                       return_val_if_nok (error, FALSE);
+               klass = mono_class_from_mono_type (instance);
+       }
 
-                       MonoClass *klass = mono_class_from_mono_type (tb);
-                       gparam->mbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
-                       gparam->mbuilder->generic_container->is_method = TRUE;
-                       /* 
-                        * Cannot set owner.method, since the MonoMethod is not created yet.
-                        * Set the image field instead, so type_in_image () works.
-                        */
-                       gparam->mbuilder->generic_container->is_anonymous = TRUE;
-                       gparam->mbuilder->generic_container->owner.image = klass->image;
-               }
-               param->param.owner = gparam->mbuilder->generic_container;
-       } else if (gparam->tbuilder) {
-               if (!gparam->tbuilder->generic_container) {
-                       MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->tbuilder, error);
-                       return_val_if_nok (error, FALSE);
-                       MonoClass *klass = mono_class_from_mono_type (tb);
-                       gparam->tbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
-                       gparam->tbuilder->generic_container->owner.klass = klass;
+       for (mod = info->modifiers; mod; mod = mod->next) {
+               modval = GPOINTER_TO_UINT (mod->data);
+               if (!modval) { /* byref: must be last modifier */
+                       return &klass->this_arg;
+               } else if (modval == -1) {
+                       klass = mono_ptr_class_get (&klass->byval_arg);
+               } else if (modval == -2) {
+                       bounded = TRUE;
+               } else { /* array rank */
+                       klass = mono_bounded_array_class_get (klass, modval, bounded);
                }
-               param->param.owner = gparam->tbuilder->generic_container;
        }
 
-       pklass = mono_class_from_generic_parameter_internal ((MonoGenericParam *) param);
-
-       gparam->type.type = &pklass->byval_arg;
+       return &klass->byval_arg;
+}
 
-       mono_class_set_ref_info (pklass, gparam);
-       mono_image_append_class_to_reflection_info_set (pklass);
+/*
+ * mono_reflection_get_type:
+ * @image: a metadata context
+ * @info: type description structure
+ * @ignorecase: flag for case-insensitive string compares
+ * @type_resolve: whenever type resolve was already tried
+ *
+ * Build a MonoType from the type description in @info.
+ * 
+ */
 
-       return TRUE;
+MonoType*
+mono_reflection_get_type (MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve) {
+       MonoError error;
+       MonoType *result = mono_reflection_get_type_with_rootimage (image, image, info, ignorecase, type_resolve, &error);
+       mono_error_cleanup (&error);
+       return result;
 }
 
-void
-ves_icall_GenericTypeParameterBuilder_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
-{
-       MonoError error;
-       (void) reflection_initialize_generic_parameter (gparam, &error);
-       mono_error_set_pending_exception (&error);
+/**
+ * mono_reflection_get_type_checked:
+ * @rootimage: the image of the currently active managed caller
+ * @image: a metadata context
+ * @info: type description structure
+ * @ignorecase: flag for case-insensitive string compares
+ * @type_resolve: whenever type resolve was already tried
+ * @error: set on error.
+ *
+ * Build a MonoType from the type description in @info. On failure returns NULL and sets @error.
+ *
+ */
+MonoType*
+mono_reflection_get_type_checked (MonoImage *rootimage, MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve, MonoError *error) {
+       mono_error_init (error);
+       return mono_reflection_get_type_with_rootimage (rootimage, image, info, ignorecase, type_resolve, error);
 }
 
 
-static MonoArray *
-reflection_sighelper_get_signature_local (MonoReflectionSigHelper *sig, MonoError *error)
+static MonoType*
+mono_reflection_get_type_internal_dynamic (MonoImage *rootimage, MonoAssembly *assembly, MonoTypeNameParse *info, gboolean ignorecase, MonoError *error)
 {
-       MonoReflectionModuleBuilder *module = sig->module;
-       MonoDynamicImage *assembly = module != NULL ? module->dynamic_image : NULL;
-       guint32 na = sig->arguments ? mono_array_length (sig->arguments) : 0;
-       guint32 buflen, i;
-       MonoArray *result;
-       SigBuffer buf;
+       MonoReflectionAssemblyBuilder *abuilder;
+       MonoType *type;
+       int i;
 
        mono_error_init (error);
+       g_assert (assembly_is_dynamic (assembly));
+       abuilder = (MonoReflectionAssemblyBuilder*)mono_assembly_get_object_checked (((MonoDynamicAssembly*)assembly)->domain, assembly, error);
+       if (!abuilder)
+               return NULL;
 
-       check_array_for_usertypes (sig->arguments, error);
-       return_val_if_nok (error, NULL);
-
-       sigbuffer_init (&buf, 32);
+       /* Enumerate all modules */
 
-       sigbuffer_add_value (&buf, 0x07);
-       sigbuffer_add_value (&buf, na);
-       if (assembly != NULL){
-               for (i = 0; i < na; ++i) {
-                       MonoReflectionType *type = mono_array_get (sig->arguments, MonoReflectionType*, i);
-                       encode_reflection_type (assembly, type, &buf, error);
-                       if (!is_ok (error)) goto fail;
+       type = NULL;
+       if (abuilder->modules) {
+               for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
+                       MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
+                       type = mono_reflection_get_type_internal (rootimage, &mb->dynamic_image->image, info, ignorecase, error);
+                       if (type)
+                               break;
+                       if (!mono_error_ok (error))
+                               return NULL;
                }
        }
 
-       buflen = buf.p - buf.buf;
-       result = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, buflen, error);
-       if (!is_ok (error)) goto fail;
-       memcpy (mono_array_addr (result, char, 0), buf.buf, buflen);
-       sigbuffer_free (&buf);
-       return result;
-fail:
-       sigbuffer_free (&buf);
-       return NULL;
-}
+       if (!type && abuilder->loaded_modules) {
+               for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
+                       MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
+                       type = mono_reflection_get_type_internal (rootimage, mod->image, info, ignorecase, error);
+                       if (type)
+                               break;
+                       if (!mono_error_ok (error))
+                               return NULL;
+               }
+       }
 
-MonoArray *
-ves_icall_SignatureHelper_get_signature_local (MonoReflectionSigHelper *sig)
-{
-       MonoError error;
-       MonoArray *result = reflection_sighelper_get_signature_local (sig, &error);
-       mono_error_set_pending_exception (&error);
-       return result;
+       return type;
 }
-
-static MonoArray *
-reflection_sighelper_get_signature_field (MonoReflectionSigHelper *sig, MonoError *error)
+       
+MonoType*
+mono_reflection_get_type_with_rootimage (MonoImage *rootimage, MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve, MonoError *error)
 {
-       MonoDynamicImage *assembly = sig->module->dynamic_image;
-       guint32 na = sig->arguments ? mono_array_length (sig->arguments) : 0;
-       guint32 buflen, i;
-       MonoArray *result;
-       SigBuffer buf;
+       MonoType *type;
+       MonoReflectionAssembly *assembly;
+       GString *fullName;
+       GList *mod;
 
        mono_error_init (error);
 
-       check_array_for_usertypes (sig->arguments, error);
+       if (image && image_is_dynamic (image))
+               type = mono_reflection_get_type_internal_dynamic (rootimage, image->assembly, info, ignorecase, error);
+       else {
+               type = mono_reflection_get_type_internal (rootimage, image, info, ignorecase, error);
+       }
        return_val_if_nok (error, NULL);
 
-       sigbuffer_init (&buf, 32);
+       if (type)
+               return type;
+       if (!mono_domain_has_type_resolve (mono_domain_get ()))
+               return NULL;
 
-       sigbuffer_add_value (&buf, 0x06);
-       for (i = 0; i < na; ++i) {
-               MonoReflectionType *type = mono_array_get (sig->arguments, MonoReflectionType*, i);
-               encode_reflection_type (assembly, type, &buf, error);
-               if (!is_ok (error))
-                       goto fail;
+       if (type_resolve) {
+               if (*type_resolve) 
+                       return NULL;
+               else
+                       *type_resolve = TRUE;
        }
+       
+       /* Reconstruct the type name */
+       fullName = g_string_new ("");
+       if (info->name_space && (info->name_space [0] != '\0'))
+               g_string_printf (fullName, "%s.%s", info->name_space, info->name);
+       else
+               g_string_printf (fullName, "%s", info->name);
+       for (mod = info->nested; mod; mod = mod->next)
+               g_string_append_printf (fullName, "+%s", (char*)mod->data);
 
-       buflen = buf.p - buf.buf;
-       result = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, buflen, error);
-       if (!is_ok (error)) goto fail;
-       memcpy (mono_array_addr (result, char, 0), buf.buf, buflen);
-       sigbuffer_free (&buf);
-
-       return result;
-fail:
-       sigbuffer_free (&buf);
-       return NULL;
-}
-
-MonoArray *
-ves_icall_SignatureHelper_get_signature_field (MonoReflectionSigHelper *sig)
-{
-       MonoError error;
-       MonoArray *result = reflection_sighelper_get_signature_field (sig, &error);
-       mono_error_set_pending_exception (&error);
-       return result;
-}
-
-typedef struct {
-       MonoMethod *handle;
-       MonoDomain *domain;
-} DynamicMethodReleaseData;
-
-/*
- * The runtime automatically clean up those after finalization.
-*/     
-static MonoReferenceQueue *dynamic_method_queue;
-
-static void
-free_dynamic_method (void *dynamic_method)
-{
-       DynamicMethodReleaseData *data = (DynamicMethodReleaseData *)dynamic_method;
-       MonoDomain *domain = data->domain;
-       MonoMethod *method = data->handle;
-       guint32 dis_link;
-
-       mono_domain_lock (domain);
-       dis_link = (guint32)(size_t)g_hash_table_lookup (domain->method_to_dyn_method, method);
-       g_hash_table_remove (domain->method_to_dyn_method, method);
-       mono_domain_unlock (domain);
-       g_assert (dis_link);
-       mono_gchandle_free (dis_link);
-
-       mono_runtime_free_method (domain, method);
-       g_free (data);
-}
-
-static gboolean
-reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb, MonoError *error)
-{
-       MonoReferenceQueue *queue;
-       MonoMethod *handle;
-       DynamicMethodReleaseData *release_data;
-       ReflectionMethodBuilder rmb;
-       MonoMethodSignature *sig;
-       MonoClass *klass;
-       MonoDomain *domain;
-       GSList *l;
-       int i;
-
-       mono_error_init (error);
-
-       if (mono_runtime_is_shutting_down ()) {
-               mono_error_set_generic_error (error, "System", "InvalidOperationException", "");
-               return FALSE;
+       assembly = mono_domain_try_type_resolve_checked ( mono_domain_get (), fullName->str, NULL, error);
+       if (!is_ok (error)) {
+               g_string_free (fullName, TRUE);
+               return NULL;
        }
 
-       if (!(queue = dynamic_method_queue)) {
-               mono_loader_lock ();
-               if (!(queue = dynamic_method_queue))
-                       queue = dynamic_method_queue = mono_gc_reference_queue_new (free_dynamic_method);
-               mono_loader_unlock ();
+       if (assembly) {
+               if (assembly_is_dynamic (assembly->assembly))
+                       type = mono_reflection_get_type_internal_dynamic (rootimage, assembly->assembly,
+                                                                         info, ignorecase, error);
+               else
+                       type = mono_reflection_get_type_internal (rootimage, assembly->assembly->image, 
+                                                                 info, ignorecase, error);
        }
+       g_string_free (fullName, TRUE);
+       return_val_if_nok (error, NULL);
+       return type;
+}
 
-       sig = dynamic_method_to_signature (mb, error);
-       return_val_if_nok (error, FALSE);
-
-       reflection_methodbuilder_from_dynamic_method (&rmb, mb);
-
-       /*
-        * Resolve references.
-        */
-       /* 
-        * Every second entry in the refs array is reserved for storing handle_class,
-        * which is needed by the ldtoken implementation in the JIT.
-        */
-       rmb.nrefs = mb->nrefs;
-       rmb.refs = g_new0 (gpointer, mb->nrefs + 1);
-       for (i = 0; i < mb->nrefs; i += 2) {
-               MonoClass *handle_class;
-               gpointer ref;
-               MonoObject *obj = mono_array_get (mb->refs, MonoObject*, i);
-
-               if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
-                       MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
-                       /*
-                        * The referenced DynamicMethod should already be created by the managed
-                        * code, except in the case of circular references. In that case, we store
-                        * method in the refs array, and fix it up later when the referenced 
-                        * DynamicMethod is created.
-                        */
-                       if (method->mhandle) {
-                               ref = method->mhandle;
-                       } else {
-                               /* FIXME: GC object stored in unmanaged memory */
-                               ref = method;
+void
+mono_reflection_free_type_info (MonoTypeNameParse *info)
+{
+       g_list_free (info->modifiers);
+       g_list_free (info->nested);
 
-                               /* FIXME: GC object stored in unmanaged memory */
-                               method->referenced_by = g_slist_append (method->referenced_by, mb);
-                       }
-                       handle_class = mono_defaults.methodhandle_class;
-               } else {
-                       MonoException *ex = NULL;
-                       ref = resolve_object (mb->module->image, obj, &handle_class, NULL, error);
-                       if (!is_ok  (error)) {
-                               g_free (rmb.refs);
-                               return FALSE;
-                       }
-                       if (!ref)
-                               ex = mono_get_exception_type_load (NULL, NULL);
-                       else if (mono_security_core_clr_enabled ())
-                               ex = mono_security_core_clr_ensure_dynamic_method_resolved_object (ref, handle_class);
-
-                       if (ex) {
-                               g_free (rmb.refs);
-                               mono_error_set_exception_instance (error, ex);
-                               return FALSE;
-                       }
-               }
+       if (info->type_arguments) {
+               int i;
 
-               rmb.refs [i] = ref; /* FIXME: GC object stored in unmanaged memory (change also resolve_object() signature) */
-               rmb.refs [i + 1] = handle_class;
-       }               
+               for (i = 0; i < info->type_arguments->len; i++) {
+                       MonoTypeNameParse *subinfo = (MonoTypeNameParse *)g_ptr_array_index (info->type_arguments, i);
 
-       if (mb->owner) {
-               MonoType *owner_type = mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner, error);
-               if (!is_ok (error)) {
-                       g_free (rmb.refs);
-                       return FALSE;
+                       mono_reflection_free_type_info (subinfo);
+                       /*We free the subinfo since it is allocated by _mono_reflection_parse_type*/
+                       g_free (subinfo);
                }
-               klass = mono_class_from_mono_type (owner_type);
-       } else {
-               klass = mono_defaults.object_class;
-       }
-
-       mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
-       g_free (rmb.refs);
-       return_val_if_nok (error, FALSE);
-
-       release_data = g_new (DynamicMethodReleaseData, 1);
-       release_data->handle = handle;
-       release_data->domain = mono_object_get_domain ((MonoObject*)mb);
-       if (!mono_gc_reference_queue_add (queue, (MonoObject*)mb, release_data))
-               g_free (release_data);
-
-       /* Fix up refs entries pointing at us */
-       for (l = mb->referenced_by; l; l = l->next) {
-               MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)l->data;
-               MonoMethodWrapper *wrapper = (MonoMethodWrapper*)method->mhandle;
-               gpointer *data;
-               
-               g_assert (method->mhandle);
 
-               data = (gpointer*)wrapper->method_data;
-               for (i = 0; i < GPOINTER_TO_UINT (data [0]); i += 2) {
-                       if ((data [i + 1] == mb) && (data [i + 1 + 1] == mono_defaults.methodhandle_class))
-                               data [i + 1] = mb->mhandle;
-               }
+               g_ptr_array_free (info->type_arguments, TRUE);
        }
-       g_slist_free (mb->referenced_by);
-
-       /* ilgen is no longer needed */
-       mb->ilgen = NULL;
-
-       domain = mono_domain_get ();
-       mono_domain_lock (domain);
-       if (!domain->method_to_dyn_method)
-               domain->method_to_dyn_method = g_hash_table_new (NULL, NULL);
-       g_hash_table_insert (domain->method_to_dyn_method, handle, (gpointer)(size_t)mono_gchandle_new_weakref ((MonoObject *)mb, TRUE));
-       mono_domain_unlock (domain);
-
-       return TRUE;
 }
 
-void
-ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
-{
-       MonoError error;
-       (void) reflection_create_dynamic_method (mb, &error);
-       mono_error_set_pending_exception (&error);
-}
-
-#endif /* DISABLE_REFLECTION_EMIT */
-
-/**
- * 
- * mono_reflection_is_valid_dynamic_token:
- * 
- * Returns TRUE if token is valid.
+/*
+ * mono_reflection_type_from_name:
+ * @name: type name.
+ * @image: a metadata context (can be NULL).
+ *
+ * Retrieves a MonoType from its @name. If the name is not fully qualified,
+ * it defaults to get the type from @image or, if @image is NULL or loading
+ * from it fails, uses corlib.
  * 
  */
-gboolean
-mono_reflection_is_valid_dynamic_token (MonoDynamicImage *image, guint32 token)
-{
-       return lookup_dyn_token (image, token) != NULL;
-}
-
-MonoMethodSignature *
-mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token, MonoError *error)
+MonoType*
+mono_reflection_type_from_name (char *name, MonoImage *image)
 {
-       MonoMethodSignature *sig;
-       g_assert (image_is_dynamic (image));
-
-       mono_error_init (error);
-
-       sig = (MonoMethodSignature *)g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
-       if (sig)
-               return sig;
-
-       return mono_method_signature_checked (method, error);
+       MonoError error;
+       MonoType  *result = mono_reflection_type_from_name_checked (name, image, &error);
+       mono_error_cleanup (&error);
+       return result;
 }
 
-#ifndef DISABLE_REFLECTION_EMIT
-
 /**
- * mono_reflection_lookup_dynamic_token:
- *
- * Finish the Builder object pointed to by TOKEN and return the corresponding
- * runtime structure. If HANDLE_CLASS is not NULL, it is set to the class required by 
- * mono_ldtoken. If valid_token is TRUE, assert if it is not found in the token->object
- * mapping table.
+ * mono_reflection_type_from_name_checked:
+ * @name: type name.
+ * @image: a metadata context (can be NULL).
+ * @error: set on errror.
  *
- * LOCKING: Take the loader lock
+ * Retrieves a MonoType from its @name. If the name is not fully qualified,
+ * it defaults to get the type from @image or, if @image is NULL or loading
+ * from it fails, uses corlib.  On failure returns NULL and sets @error.
+ * 
  */
-gpointer
-mono_reflection_lookup_dynamic_token (MonoImage *image, guint32 token, gboolean valid_token, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
+MonoType*
+mono_reflection_type_from_name_checked (char *name, MonoImage *image, MonoError *error)
 {
-       MonoDynamicImage *assembly = (MonoDynamicImage*)image;
-       MonoObject *obj;
-       MonoClass *klass;
+       MonoType *type = NULL;
+       MonoTypeNameParse info;
+       char *tmp;
 
        mono_error_init (error);
+       /* Make a copy since parse_type modifies its argument */
+       tmp = g_strdup (name);
        
-       obj = lookup_dyn_token (assembly, token);
-       if (!obj) {
-               if (valid_token)
-                       g_error ("Could not find required dynamic token 0x%08x", token);
-               else {
-                       mono_error_set_execution_engine (error, "Could not find dynamic token 0x%08x", token);
+       /*g_print ("requested type %s\n", str);*/
+       if (mono_reflection_parse_type (tmp, &info)) {
+               type = _mono_reflection_get_type_from_info (&info, image, FALSE, error);
+               if (!is_ok (error)) {
+                       g_free (tmp);
+                       mono_reflection_free_type_info (&info);
                        return NULL;
                }
        }
 
-       if (!handle_class)
-               handle_class = &klass;
-       gpointer result = resolve_object (image, obj, handle_class, context, error);
-       return result;
+       g_free (tmp);
+       mono_reflection_free_type_info (&info);
+       return type;
 }
 
 /*
- * ensure_complete_type:
+ * mono_reflection_get_token:
  *
- *   Ensure that KLASS is completed if it is a dynamic type, or references
- * dynamic types.
+ *   Return the metadata token of OBJ which should be an object
+ * representing a metadata element.
  */
-static void
-ensure_complete_type (MonoClass *klass, MonoError *error)
+guint32
+mono_reflection_get_token (MonoObject *obj)
 {
-       mono_error_init (error);
-
-       if (image_is_dynamic (klass->image) && !klass->wastypebuilder && mono_class_get_ref_info (klass)) {
-               MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
+       MonoError error;
+       guint32 result = mono_reflection_get_token_checked (obj, &error);
+       mono_error_assert_ok (&error);
+       return result;
+}
 
-               mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
-               return_if_nok (error);
+/**
+ * mono_reflection_get_token_checked:
+ * @obj: the object
+ * @error: set on error
+ *
+ *   Return the metadata token of @obj which should be an object
+ * representing a metadata element.  On failure sets @error.
+ */
+guint32
+mono_reflection_get_token_checked (MonoObject *obj, MonoError *error)
+{
+       MonoClass *klass;
+       guint32 token = 0;
 
-               // Asserting here could break a lot of code
-               //g_assert (klass->wastypebuilder);
-       }
+       mono_error_init (error);
 
-       if (klass->generic_class) {
-               MonoGenericInst *inst = klass->generic_class->context.class_inst;
-               int i;
+       klass = obj->vtable->klass;
 
-               for (i = 0; i < inst->type_argc; ++i) {
-                       ensure_complete_type (mono_class_from_mono_type (inst->type_argv [i]), error);
-                       return_if_nok (error);
-               }
-       }
-}
+       if (strcmp (klass->name, "MethodBuilder") == 0) {
+               MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
 
-static gpointer
-resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
-{
-       gpointer result = NULL;
+               token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
+       } else if (strcmp (klass->name, "ConstructorBuilder") == 0) {
+               MonoReflectionCtorBuilder *mb = (MonoReflectionCtorBuilder *)obj;
 
-       mono_error_init (error);
+               token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
+       } else if (strcmp (klass->name, "FieldBuilder") == 0) {
+               MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)obj;
 
-       if (strcmp (obj->vtable->klass->name, "String") == 0) {
-               result = mono_string_intern_checked ((MonoString*)obj, error);
-               return_val_if_nok (error, NULL);
-               *handle_class = mono_defaults.string_class;
-               g_assert (result);
-       } else if (strcmp (obj->vtable->klass->name, "RuntimeType") == 0) {
+               token = fb->table_idx | MONO_TOKEN_FIELD_DEF;
+       } else if (strcmp (klass->name, "TypeBuilder") == 0) {
+               MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)obj;
+               token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
+       } else if (strcmp (klass->name, "RuntimeType") == 0) {
                MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
-               return_val_if_nok (error, NULL);
+               return_val_if_nok (error, 0);
                MonoClass *mc = mono_class_from_mono_type (type);
                if (!mono_class_init (mc)) {
                        mono_error_set_for_class_failure (error, mc);
-                       return NULL;
+                       return 0;
                }
 
-               if (context) {
-                       MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
-                       return_val_if_nok (error, NULL);
-
-                       result = mono_class_from_mono_type (inflated);
-                       mono_metadata_free_type (inflated);
+               token = mc->type_token;
+       } else if (strcmp (klass->name, "MonoCMethod") == 0 ||
+                  strcmp (klass->name, "MonoMethod") == 0 ||
+                  strcmp (klass->name, "MonoGenericMethod") == 0 ||
+                  strcmp (klass->name, "MonoGenericCMethod") == 0) {
+               MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
+               if (m->method->is_inflated) {
+                       MonoMethodInflated *inflated = (MonoMethodInflated *) m->method;
+                       return inflated->declaring->token;
                } else {
-                       result = mono_class_from_mono_type (type);
-               }
-               *handle_class = mono_defaults.typehandle_class;
-               g_assert (result);
-       } else if (strcmp (obj->vtable->klass->name, "MonoMethod") == 0 ||
-                  strcmp (obj->vtable->klass->name, "MonoCMethod") == 0 ||
-                  strcmp (obj->vtable->klass->name, "MonoGenericCMethod") == 0 ||
-                  strcmp (obj->vtable->klass->name, "MonoGenericMethod") == 0) {
-               result = ((MonoReflectionMethod*)obj)->method;
-               if (context) {
-                       result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
-                       mono_error_assert_ok (error);
-               }
-               *handle_class = mono_defaults.methodhandle_class;
-               g_assert (result);
-       } else if (strcmp (obj->vtable->klass->name, "MethodBuilder") == 0) {
-               MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)obj;
-               result = mb->mhandle;
-               if (!result) {
-                       /* Type is not yet created */
-                       MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
-
-                       mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
-                       return_val_if_nok (error, NULL);
-
-                       /*
-                        * Hopefully this has been filled in by calling CreateType() on the
-                        * TypeBuilder.
-                        */
-                       /*
-                        * TODO: This won't work if the application finishes another 
-                        * TypeBuilder instance instead of this one.
-                        */
-                       result = mb->mhandle;
-               }
-               if (context) {
-                       result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
-                       mono_error_assert_ok (error);
+                       token = m->method->token;
                }
-               *handle_class = mono_defaults.methodhandle_class;
-       } else if (strcmp (obj->vtable->klass->name, "ConstructorBuilder") == 0) {
-               MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder*)obj;
+       } else if (strcmp (klass->name, "MonoField") == 0) {
+               MonoReflectionField *f = (MonoReflectionField*)obj;
 
-               result = cb->mhandle;
-               if (!result) {
-                       MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)cb->type;
+               token = mono_class_get_field_token (f->field);
+       } else if (strcmp (klass->name, "MonoProperty") == 0) {
+               MonoReflectionProperty *p = (MonoReflectionProperty*)obj;
 
-                       mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
-                       return_val_if_nok (error, NULL);
-                       result = cb->mhandle;
-               }
-               if (context) {
-                       result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
-                       mono_error_assert_ok (error);
-               }
-               *handle_class = mono_defaults.methodhandle_class;
-       } else if (strcmp (obj->vtable->klass->name, "MonoField") == 0) {
-               MonoClassField *field = ((MonoReflectionField*)obj)->field;
+               token = mono_class_get_property_token (p->property);
+       } else if (strcmp (klass->name, "MonoEvent") == 0) {
+               MonoReflectionMonoEvent *p = (MonoReflectionMonoEvent*)obj;
 
-               ensure_complete_type (field->parent, error);
-               return_val_if_nok (error, NULL);
+               token = mono_class_get_event_token (p->event);
+       } else if (strcmp (klass->name, "ParameterInfo") == 0 || strcmp (klass->name, "MonoParameterInfo") == 0) {
+               MonoReflectionParameter *p = (MonoReflectionParameter*)obj;
+               MonoClass *member_class = mono_object_class (p->MemberImpl);
+               g_assert (mono_class_is_reflection_method_or_constructor (member_class));
 
-               if (context) {
-                       MonoType *inflated = mono_class_inflate_generic_type_checked (&field->parent->byval_arg, context, error);
-                       return_val_if_nok (error, NULL);
-
-                       MonoClass *klass = mono_class_from_mono_type (inflated);
-                       MonoClassField *inflated_field;
-                       gpointer iter = NULL;
-                       mono_metadata_free_type (inflated);
-                       while ((inflated_field = mono_class_get_fields (klass, &iter))) {
-                               if (!strcmp (field->name, inflated_field->name))
-                                       break;
-                       }
-                       g_assert (inflated_field && !strcmp (field->name, inflated_field->name));
-                       result = inflated_field;
-               } else {
-                       result = field;
-               }
-               *handle_class = mono_defaults.fieldhandle_class;
-               g_assert (result);
-       } else if (strcmp (obj->vtable->klass->name, "FieldBuilder") == 0) {
-               MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder*)obj;
-               result = fb->handle;
+               token = mono_method_get_param_token (((MonoReflectionMethod*)p->MemberImpl)->method, p->PositionImpl);
+       } else if (strcmp (klass->name, "Module") == 0 || strcmp (klass->name, "MonoModule") == 0) {
+               MonoReflectionModule *m = (MonoReflectionModule*)obj;
 
-               if (!result) {
-                       MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)fb->typeb;
+               token = m->token;
+       } else if (strcmp (klass->name, "Assembly") == 0 || strcmp (klass->name, "MonoAssembly") == 0) {
+               token = mono_metadata_make_token (MONO_TABLE_ASSEMBLY, 1);
+       } else {
+               mono_error_set_not_implemented (error, "MetadataToken is not supported for type '%s.%s'",
+                                               klass->name_space, klass->name);
+               return 0;
+       }
 
-                       mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
-                       return_val_if_nok (error, NULL);
-                       result = fb->handle;
-               }
+       return token;
+}
 
-               if (fb->handle && fb->handle->parent->generic_container) {
-                       MonoClass *klass = fb->handle->parent;
-                       MonoType *type = mono_class_inflate_generic_type_checked (&klass->byval_arg, context, error);
-                       return_val_if_nok (error, NULL);
 
-                       MonoClass *inflated = mono_class_from_mono_type (type);
+gboolean
+mono_reflection_is_usertype (MonoReflectionType *ref)
+{
+       MonoClass *klass = mono_object_class (ref);
+       return klass->image != mono_defaults.corlib || strcmp ("TypeDelegator", klass->name) == 0;
+}
 
-                       result = mono_class_get_field_from_name (inflated, mono_field_get_name (fb->handle));
-                       g_assert (result);
-                       mono_metadata_free_type (type);
-               }
-               *handle_class = mono_defaults.fieldhandle_class;
-       } else if (strcmp (obj->vtable->klass->name, "TypeBuilder") == 0) {
-               MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
-               MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
-               return_val_if_nok (error, NULL);
-               MonoClass *klass;
+/**
+ * mono_reflection_bind_generic_parameters:
+ * @type: a managed type object (which should be some kind of generic (instance? definition?))
+ * @type_args: the number of type arguments to bind
+ * @types: array of type arguments
+ * @error: set on error
+ *
+ * Given a managed type object for a generic type instance, binds each of its arguments to the specified types.
+ * Returns the MonoType* for the resulting type instantiation.  On failure returns NULL and sets @error.
+ */
+MonoType*
+mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types, MonoError *error)
+{
+       MonoClass *klass;
+       MonoReflectionTypeBuilder *tb = NULL;
+       gboolean is_dynamic = FALSE;
+       MonoClass *geninst;
 
-               klass = type->data.klass;
-               if (klass->wastypebuilder) {
-                       /* Already created */
-                       result = klass;
-               }
-               else {
-                       mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
-                       return_val_if_nok (error, NULL);
-                       result = type->data.klass;
-                       g_assert (result);
-               }
-               *handle_class = mono_defaults.typehandle_class;
-       } else if (strcmp (obj->vtable->klass->name, "SignatureHelper") == 0) {
-               MonoReflectionSigHelper *helper = (MonoReflectionSigHelper*)obj;
-               MonoMethodSignature *sig;
-               int nargs, i;
-
-               if (helper->arguments)
-                       nargs = mono_array_length (helper->arguments);
-               else
-                       nargs = 0;
+       mono_error_init (error);
+       
+       mono_loader_lock ();
 
-               sig = mono_metadata_signature_alloc (image, nargs);
-               sig->explicit_this = helper->call_conv & 64 ? 1 : 0;
-               sig->hasthis = helper->call_conv & 32 ? 1 : 0;
+       if (mono_is_sre_type_builder (mono_object_class (type))) {
+               tb = (MonoReflectionTypeBuilder *) type;
 
-               if (helper->unmanaged_call_conv) { /* unmanaged */
-                       sig->call_convention = helper->unmanaged_call_conv - 1;
-                       sig->pinvoke = TRUE;
-               } else if (helper->call_conv & 0x02) {
-                       sig->call_convention = MONO_CALL_VARARG;
-               } else {
-                       sig->call_convention = MONO_CALL_DEFAULT;
-               }
+               is_dynamic = TRUE;
+       } else if (mono_is_sre_generic_instance (mono_object_class (type))) {
+               MonoReflectionGenericClass *rgi = (MonoReflectionGenericClass *) type;
+               MonoReflectionType *gtd = rgi->generic_type;
 
-               sig->param_count = nargs;
-               /* TODO: Copy type ? */
-               sig->ret = helper->return_type->type;
-               for (i = 0; i < nargs; ++i) {
-                       sig->params [i] = mono_type_array_get_and_resolve (helper->arguments, i, error);
-                       if (!is_ok (error)) {
-                               image_g_free (image, sig);
-                               return NULL;
-                       }
+               if (mono_is_sre_type_builder (mono_object_class (gtd))) {
+                       tb = (MonoReflectionTypeBuilder *)gtd;
+                       is_dynamic = TRUE;
                }
+       }
 
-               result = sig;
-               *handle_class = NULL;
-       } else if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
-               MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
-               /* Already created by the managed code */
-               g_assert (method->mhandle);
-               result = method->mhandle;
-               *handle_class = mono_defaults.methodhandle_class;
-       } else if (strcmp (obj->vtable->klass->name, "GenericTypeParameterBuilder") == 0) {
-               MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
-               return_val_if_nok (error, NULL);
-               type = mono_class_inflate_generic_type_checked (type, context, error);
-               return_val_if_nok (error, NULL);
-
-               result = mono_class_from_mono_type (type);
-               *handle_class = mono_defaults.typehandle_class;
-               g_assert (result);
-               mono_metadata_free_type (type);
-       } else if (strcmp (obj->vtable->klass->name, "MonoGenericClass") == 0) {
-               MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
-               return_val_if_nok (error, NULL);
-               type = mono_class_inflate_generic_type_checked (type, context, error);
-               return_val_if_nok (error, NULL);
-
-               result = mono_class_from_mono_type (type);
-               *handle_class = mono_defaults.typehandle_class;
-               g_assert (result);
-               mono_metadata_free_type (type);
-       } else if (strcmp (obj->vtable->klass->name, "FieldOnTypeBuilderInst") == 0) {
-               MonoReflectionFieldOnTypeBuilderInst *f = (MonoReflectionFieldOnTypeBuilderInst*)obj;
-               MonoClass *inflated;
-               MonoType *type;
-               MonoClassField *field;
-
-               if (is_sre_field_builder (mono_object_class (f->fb)))
-                       field = ((MonoReflectionFieldBuilder*)f->fb)->handle;
-               else if (is_sr_mono_field (mono_object_class (f->fb)))
-                       field = ((MonoReflectionField*)f->fb)->field;
-               else
-                       g_error ("resolve_object:: can't handle a FTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (f->fb)));
-
-               MonoType *finst = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst, error);
-               return_val_if_nok (error, NULL);
-               type = mono_class_inflate_generic_type_checked (finst, context, error);
-               return_val_if_nok (error, NULL);
-
-               inflated = mono_class_from_mono_type (type);
-
-               result = field = mono_class_get_field_from_name (inflated, mono_field_get_name (field));
-               ensure_complete_type (field->parent, error);
-               if (!is_ok (error)) {
-                       mono_metadata_free_type (type);
+       /* FIXME: fix the CreateGenericParameters protocol to avoid the two stage setup of TypeBuilders */
+       if (tb && tb->generic_container) {
+               if (!mono_reflection_create_generic_class (tb, error)) {
+                       mono_loader_unlock ();
                        return NULL;
                }
-
-               g_assert (result);
-               mono_metadata_free_type (type);
-               *handle_class = mono_defaults.fieldhandle_class;
-       } else if (strcmp (obj->vtable->klass->name, "ConstructorOnTypeBuilderInst") == 0) {
-               MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj;
-               MonoType *cinst = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst, error);
-               return_val_if_nok (error, NULL);
-               MonoType *type = mono_class_inflate_generic_type_checked (cinst, context, error);
-               return_val_if_nok (error, NULL);
-
-               MonoClass *inflated_klass = mono_class_from_mono_type (type);
-               MonoMethod *method;
-
-               if (is_sre_ctor_builder (mono_object_class (c->cb)))
-                       method = ((MonoReflectionCtorBuilder *)c->cb)->mhandle;
-               else if (is_sr_mono_cmethod (mono_object_class (c->cb)))
-                       method = ((MonoReflectionMethod *)c->cb)->method;
-               else
-                       g_error ("resolve_object:: can't handle a CTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (c->cb)));
-
-               result = inflate_mono_method (inflated_klass, method, (MonoObject*)c->cb);
-               *handle_class = mono_defaults.methodhandle_class;
-               mono_metadata_free_type (type);
-       } else if (strcmp (obj->vtable->klass->name, "MethodOnTypeBuilderInst") == 0) {
-               MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
-               if (m->method_args) {
-                       result = mono_reflection_method_on_tb_inst_get_handle (m, error);
-                       return_val_if_nok (error, NULL);
-                       if (context) {
-                               result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
-                               mono_error_assert_ok (error);
-                       }
-               } else {
-                       MonoType *minst = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
-                       return_val_if_nok (error, NULL);
-                       MonoType *type = mono_class_inflate_generic_type_checked (minst, context, error);
-                       return_val_if_nok (error, NULL);
-
-                       MonoClass *inflated_klass = mono_class_from_mono_type (type);
-                       MonoMethod *method;
-
-                       if (is_sre_method_builder (mono_object_class (m->mb)))
-                               method = ((MonoReflectionMethodBuilder *)m->mb)->mhandle;
-                       else if (is_sr_mono_method (mono_object_class (m->mb)))
-                               method = ((MonoReflectionMethod *)m->mb)->method;
-                       else
-                               g_error ("resolve_object:: can't handle a MTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (m->mb)));
-
-                       result = inflate_mono_method (inflated_klass, method, (MonoObject*)m->mb);
-                       mono_metadata_free_type (type);
-               }
-               *handle_class = mono_defaults.methodhandle_class;
-       } else if (strcmp (obj->vtable->klass->name, "MonoArrayMethod") == 0) {
-               MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod*)obj;
-               MonoType *mtype;
-               MonoClass *klass;
-               MonoMethod *method;
-               gpointer iter;
-               char *name;
-
-               mtype = mono_reflection_type_get_handle (m->parent, error);
-               return_val_if_nok (error, NULL);
-               klass = mono_class_from_mono_type (mtype);
-
-               /* Find the method */
-
-               name = mono_string_to_utf8_checked (m->name, error);
-               return_val_if_nok (error, NULL);
-               iter = NULL;
-               while ((method = mono_class_get_methods (klass, &iter))) {
-                       if (!strcmp (method->name, name))
-                               break;
-               }
-               g_free (name);
-
-               // FIXME:
-               g_assert (method);
-               // FIXME: Check parameters/return value etc. match
-
-               result = method;
-               *handle_class = mono_defaults.methodhandle_class;
-       } else if (is_sre_array (mono_object_get_class(obj)) ||
-                               is_sre_byref (mono_object_get_class(obj)) ||
-                               is_sre_pointer (mono_object_get_class(obj))) {
-               MonoReflectionType *ref_type = (MonoReflectionType *)obj;
-               MonoType *type = mono_reflection_type_get_handle (ref_type, error);
-               return_val_if_nok (error, NULL);
-
-               if (context) {
-                       MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
-                       return_val_if_nok (error, NULL);
-
-                       result = mono_class_from_mono_type (inflated);
-                       mono_metadata_free_type (inflated);
-               } else {
-                       result = mono_class_from_mono_type (type);
-               }
-               *handle_class = mono_defaults.typehandle_class;
-       } else {
-               g_print ("%s\n", obj->vtable->klass->name);
-               g_assert_not_reached ();
        }
-       return result;
-}
-
-#else /* DISABLE_REFLECTION_EMIT */
-
-MonoArray*
-mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) 
-{
-       g_assert_not_reached ();
-       return NULL;
-}
 
-void
-ves_icall_TypeBuilder_setup_internal_class (MonoReflectionTypeBuilder *tb)
-{
-       g_assert_not_reached ();
-}
+       MonoType *t = mono_reflection_type_get_handle (type, error);
+       if (!is_ok (error)) {
+               mono_loader_unlock ();
+               return NULL;
+       }
 
-void
-ves_icall_TypeBuilder_setup_generic_class (MonoReflectionTypeBuilder *tb)
-{
-       g_assert_not_reached ();
-}
+       klass = mono_class_from_mono_type (t);
+       if (!klass->generic_container) {
+               mono_loader_unlock ();
+               mono_error_set_type_load_class (error, klass, "Cannot bind generic parameters of a non-generic type");
+               return NULL;
+       }
 
-static gboolean
-mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error)
-{
-       g_assert_not_reached ();
-       return FALSE;
-}
+       if (klass->wastypebuilder) {
+               tb = (MonoReflectionTypeBuilder *) mono_class_get_ref_info (klass);
 
-void
-ves_icall_TypeBuilder_create_internal_class (MonoReflectionTypeBuilder *tb)
-{
-       g_assert_not_reached ();
-}
+               is_dynamic = TRUE;
+       }
 
-static void
-mono_image_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
-{
-       g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported.");
-}
+       mono_loader_unlock ();
 
-static void
-mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
-{
-       g_assert_not_reached ();
-}
+       geninst = mono_class_bind_generic_parameters (klass, type_argc, types, is_dynamic);
 
-MonoReflectionModule *
-mono_image_load_module_dynamic (MonoReflectionAssemblyBuilder *ab, MonoString *fileName, MonoError *error)
-{
-       g_assert_not_reached ();
-       return NULL;
+       return &geninst->byval_arg;
 }
 
-guint32
-mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
+MonoClass*
+mono_class_bind_generic_parameters (MonoClass *klass, int type_argc, MonoType **types, gboolean is_dynamic)
 {
-       g_assert_not_reached ();
-       return 0;
-}
+       MonoGenericClass *gclass;
+       MonoGenericInst *inst;
 
-guint32
-mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types, MonoError *error)
-{
-       g_assert_not_reached ();
-       return 0;
-}
+       g_assert (klass->generic_container);
 
-guint32
-mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, 
-                        gboolean create_open_instance, gboolean register_token, MonoError *error)
-{
-       g_assert_not_reached ();
-       return 0;
-}
+       inst = mono_metadata_get_generic_inst (type_argc, types);
+       gclass = mono_metadata_lookup_generic_class (klass, inst, is_dynamic);
 
-void
-mono_image_register_token (MonoDynamicImage *assembly, guint32 token, MonoObject *obj)
-{
+       return mono_generic_class_get_class (gclass);
 }
 
-void
-mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields)
+static MonoReflectionMethod*
+reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, MonoArray *types, MonoError *error)
 {
-       g_assert_not_reached ();
-}
+       MonoClass *klass;
+       MonoMethod *method, *inflated;
+       MonoMethodInflated *imethod;
+       MonoGenericContext tmp_context;
+       MonoGenericInst *ginst;
+       MonoType **type_argv;
+       int count, i;
 
-void
-mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
-{
        mono_error_init (error);
-       *overrides = NULL;
-       *num_overrides = 0;
-}
 
-MonoReflectionEvent *
-ves_icall_TypeBuilder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb)
-{
-       g_assert_not_reached ();
-       return NULL;
-}
+       /*FIXME but this no longer should happen*/
+       if (!strcmp (rmethod->object.vtable->klass->name, "MethodBuilder")) {
+               method = mono_reflection_method_builder_to_mono_method ((MonoReflectionMethodBuilder*)rmethod, error);
+               return_val_if_nok (error, NULL);
+       } else {
+               method = rmethod->method;
+       }
 
-MonoReflectionType*
-ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
-{
-       g_assert_not_reached ();
-       return NULL;
-}
+       klass = method->klass;
 
-void
-ves_icall_GenericTypeParameterBuilder_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
-{
-       g_assert_not_reached ();
-}
+       if (method->is_inflated)
+               method = ((MonoMethodInflated *) method)->declaring;
 
-MonoArray *
-ves_icall_SignatureHelper_get_signature_local (MonoReflectionSigHelper *sig)
-{
-       g_assert_not_reached ();
-       return NULL;
-}
+       count = mono_method_signature (method)->generic_param_count;
+       if (count != mono_array_length (types))
+               return NULL;
 
-MonoArray *
-ves_icall_SignatureHelper_get_signature_field (MonoReflectionSigHelper *sig)
-{
-       g_assert_not_reached ();
-       return NULL;
-}
+       type_argv = g_new0 (MonoType *, count);
+       for (i = 0; i < count; i++) {
+               MonoReflectionType *garg = (MonoReflectionType *)mono_array_get (types, gpointer, i);
+               type_argv [i] = mono_reflection_type_get_handle (garg, error);
+               if (!is_ok (error)) {
+                       g_free (type_argv);
+                       return NULL;
+               }
+       }
+       ginst = mono_metadata_get_generic_inst (count, type_argv);
+       g_free (type_argv);
 
-void 
-ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
-{
-}
+       tmp_context.class_inst = klass->generic_class ? klass->generic_class->context.class_inst : NULL;
+       tmp_context.method_inst = ginst;
 
-gpointer
-mono_reflection_lookup_dynamic_token (MonoImage *image, guint32 token, gboolean valid_token, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
-{
-       mono_error_init (error);
-       return NULL;
+       inflated = mono_class_inflate_generic_method_checked (method, &tmp_context, error);
+       mono_error_assert_ok (error);
+       imethod = (MonoMethodInflated *) inflated;
+
+       /*FIXME but I think this is no longer necessary*/
+       if (image_is_dynamic (method->klass->image)) {
+               MonoDynamicImage *image = (MonoDynamicImage*)method->klass->image;
+               /*
+                * This table maps metadata structures representing inflated methods/fields
+                * to the reflection objects representing their generic definitions.
+                */
+               mono_image_lock ((MonoImage*)image);
+               mono_g_hash_table_insert (image->generic_def_objects, imethod, rmethod);
+               mono_image_unlock ((MonoImage*)image);
+       }
+
+       if (!mono_verifier_is_method_valid_generic_instantiation (inflated)) {
+               mono_error_set_argument (error, "typeArguments", "Invalid generic arguments");
+               return NULL;
+       }
+       
+       MonoReflectionMethod *ret = mono_method_get_object_checked (mono_object_domain (rmethod), inflated, NULL, error);
+       return ret;
 }
 
-MonoType*
-mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
+MonoReflectionMethod*
+ves_icall_MethodBuilder_MakeGenericMethod (MonoReflectionMethod *rmethod, MonoArray *types)
 {
-       mono_error_init (error);
-       if (!ref)
-               return NULL;
-       return ref->type;
+       MonoError error;
+       MonoReflectionMethod *result = reflection_bind_generic_method_parameters (rmethod, types, &error);
+       mono_error_set_pending_exception (&error);
+       return result;
 }
 
-void
-mono_reflection_free_dynamic_generic_class (MonoGenericClass *gclass)
+MonoReflectionMethod*
+ves_icall_MonoMethod_MakeGenericMethod_impl (MonoReflectionMethod *rmethod, MonoArray *types)
 {
-       g_assert_not_reached ();
+       MonoError error;
+       MonoReflectionMethod *result = reflection_bind_generic_method_parameters (rmethod, types, &error);
+       mono_error_set_pending_exception (&error);
+       return result;
 }
 
-#endif /* DISABLE_REFLECTION_EMIT */
 
 /* SECURITY_ACTION_* are defined in mono/metadata/tabledefs.h */
 const static guint32 declsec_flags_map[] = {
@@ -14945,207 +2863,14 @@ mono_reflection_assembly_get_assembly (MonoReflectionAssembly *refassembly)
        return refassembly->assembly;
 }
 
-gint32
-ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, gboolean create_open_instance)
-{
-       MONO_CHECK_ARG_NULL (obj, 0);
-
-       MonoError error;
-       gint32 result = mono_image_create_token (mb->dynamic_image, obj, create_open_instance, TRUE, &error);
-       mono_error_set_pending_exception (&error);
-       return result;
-}
-
-gint32
-ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
-                                       MonoReflectionMethod *method,
-                                       MonoArray *opt_param_types)
-{
-       MONO_CHECK_ARG_NULL (method, 0);
-
-       MonoError error;
-       gint32 result = mono_image_create_method_token (
-               mb->dynamic_image, (MonoObject *) method, opt_param_types, &error);
-       mono_error_set_pending_exception (&error);
-       return result;
-}
-
-void
-ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
-{
-       MonoError error;
-       mono_image_create_pefile (mb, file, &error);
-       mono_error_set_pending_exception (&error);
-}
-
-void
-ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
-{
-       MonoError error;
-       mono_image_build_metadata (mb, &error);
-       mono_error_set_pending_exception (&error);
-}
-
-void
-ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, guint32 token)
-{
-       mono_image_register_token (mb->dynamic_image, token, obj);
-}
-
-MonoObject*
-ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilder *mb, guint32 token)
-{
-       MonoObject *obj;
-
-       mono_loader_lock ();
-       obj = (MonoObject *)mono_g_hash_table_lookup (mb->dynamic_image->tokens, GUINT_TO_POINTER (token));
-       mono_loader_unlock ();
-
-       return obj;
-}
-
-MonoReflectionModule*
-ves_icall_AssemblyBuilder_InternalAddModule (MonoReflectionAssemblyBuilder *ab, MonoString *fileName)
-{
-       MonoError error;
-       MonoReflectionModule *result = mono_image_load_module_dynamic (ab, fileName, &error);
-       mono_error_set_pending_exception (&error);
-       return result;
-}
-
 /**
- * ves_icall_TypeBuilder_create_generic_class:
- * @tb: a TypeBuilder object
+ * mono_class_from_mono_type_handle:
+ * @reftype: the System.Type handle
  *
- * (icall)
- * Creates the generic class after all generic parameters have been added.
+ * Returns the MonoClass* corresponding to the given type.
  */
-void
-ves_icall_TypeBuilder_create_generic_class (MonoReflectionTypeBuilder *tb)
-{
-       MonoError error;
-       (void) mono_reflection_create_generic_class (tb, &error);
-       mono_error_set_pending_exception (&error);
-}
-
-#ifndef DISABLE_REFLECTION_EMIT
-MonoArray*
-ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
-{
-       MonoError error;
-       MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
-       mono_error_set_pending_exception (&error);
-       return result;
-}
-#endif
-
-void
-ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
-{
-       mono_image_basic_init (assemblyb);
-}
-
-MonoBoolean
-ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
-{
-       return is_generic_parameter (tb->type.type);
-}
-
-void
-ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
-                                                                          MonoReflectionType *t)
-{
-       enumtype->type = t->type;
-}
-
-MonoReflectionType*
-ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
-{
-       MonoError error;
-       MonoReflectionType *ret;
-       MonoClass *klass;
-       int isbyref = 0, rank;
-       char *p;
-       char *str = mono_string_to_utf8_checked (smodifiers, &error);
-       if (mono_error_set_pending_exception (&error))
-               return NULL;
-
-       klass = mono_class_from_mono_type (tb->type.type);
-       p = str;
-       /* logic taken from mono_reflection_parse_type(): keep in sync */
-       while (*p) {
-               switch (*p) {
-               case '&':
-                       if (isbyref) { /* only one level allowed by the spec */
-                               g_free (str);
-                               return NULL;
-                       }
-                       isbyref = 1;
-                       p++;
-
-                       g_free (str);
-
-                       ret = mono_type_get_object_checked (mono_object_domain (tb), &klass->this_arg, &error);
-                       mono_error_set_pending_exception (&error);
-
-                       return ret;
-               case '*':
-                       klass = mono_ptr_class_get (&klass->byval_arg);
-                       mono_class_init (klass);
-                       p++;
-                       break;
-               case '[':
-                       rank = 1;
-                       p++;
-                       while (*p) {
-                               if (*p == ']')
-                                       break;
-                               if (*p == ',')
-                                       rank++;
-                               else if (*p != '*') { /* '*' means unknown lower bound */
-                                       g_free (str);
-                                       return NULL;
-                               }
-                               ++p;
-                       }
-                       if (*p != ']') {
-                               g_free (str);
-                               return NULL;
-                       }
-                       p++;
-                       klass = mono_array_class_get (klass, rank);
-                       mono_class_init (klass);
-                       break;
-               default:
-                       break;
-               }
-       }
-
-       g_free (str);
-
-       ret = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
-       mono_error_set_pending_exception (&error);
-
-       return ret;
-}
-
-void
-ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilder *moduleb)
-{
-       mono_image_module_basic_init (moduleb);
-}
-
-guint32
-ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilder *module, MonoString *str)
-{
-       return mono_image_insert_string (module, str);
-}
-
-void
-ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilder *moduleb, MonoReflectionType *type)
+MonoClass*
+mono_class_from_mono_type_handle (MonoReflectionTypeHandle reftype)
 {
-       MonoDynamicImage *image = moduleb->dynamic_image;
-
-       g_assert (type->type);
-       image->wrappers_type = mono_class_from_mono_type (type->type);
+       return mono_class_from_mono_type (MONO_HANDLE_RAW (reftype)->type);
 }
index 0597bdd7882fdd994391eadbe65c84ca58c0c181..09224b2f15be171f37d2107b293af76b76c47d38 100644 (file)
@@ -33,9 +33,16 @@ void sgen_bridge_describe_pointer (GCObject *object);
 gboolean sgen_is_bridge_object (GCObject *obj);
 void sgen_mark_bridge_object (GCObject *obj);
 
+gboolean sgen_bridge_handle_gc_param (const char *opt);
 gboolean sgen_bridge_handle_gc_debug (const char *opt);
 void sgen_bridge_print_gc_debug_usage (void);
 
+typedef struct {
+       char *dump_prefix;
+       gboolean accounting;
+       gboolean scc_precise_merge; // Used by Tarjan
+} SgenBridgeProcessorConfig;
+
 typedef struct {
        void (*reset_data) (void);
        void (*processing_stw_step) (void);
@@ -44,10 +51,9 @@ typedef struct {
        MonoGCBridgeObjectKind (*class_kind) (MonoClass *klass);
        void (*register_finalized_object) (GCObject *object);
        void (*describe_pointer) (GCObject *object);
-       void (*enable_accounting) (void);
 
-       // Optional-- used for debugging
-       void (*set_dump_prefix) (const char *prefix);
+       /* Should be called once, immediately after init */
+       void (*set_config) (const SgenBridgeProcessorConfig *);
 
        /*
         * These are set by processing_build_callback_data().
index 006e68c50121f32e9de1a776a9f164ead82907dd..7ec2d4386dfb5f4934169182128e402931b4f397 100644 (file)
@@ -33,6 +33,8 @@ typedef enum {
 static BridgeProcessorSelection bridge_processor_selection = BRIDGE_PROCESSOR_DEFAULT;
 // Most recently requested callbacks
 static MonoGCBridgeCallbacks pending_bridge_callbacks;
+// Configuration to be passed to bridge processor after init
+static SgenBridgeProcessorConfig bridge_processor_config;
 // Currently-in-use callbacks
 MonoGCBridgeCallbacks bridge_callbacks;
 
@@ -84,6 +86,12 @@ bridge_processor_name (const char *name)
        }
 }
 
+static gboolean
+bridge_processor_started ()
+{
+       return bridge_processor.reset_data != NULL;
+}
+
 // Initialize a single bridge processor
 static void
 init_bridge_processor (SgenBridgeProcessor *processor, BridgeProcessorSelection selection)
@@ -133,9 +141,17 @@ sgen_init_bridge ()
                bridge_callbacks = pending_bridge_callbacks;
 
                // If a bridge was registered but there is no bridge processor yet
-               if (bridge_callbacks.cross_references && !bridge_processor.reset_data)
+               if (bridge_callbacks.cross_references && !bridge_processor_started ()) {
                        init_bridge_processor (&bridge_processor, bridge_processor_selection);
 
+                       if (bridge_processor.set_config)
+                               bridge_processor.set_config (&bridge_processor_config);
+
+                       // Config is no longer needed so free its memory
+                       free (bridge_processor_config.dump_prefix);
+                       bridge_processor_config.dump_prefix = NULL;
+               }
+
                sgen_gc_unlock ();
        }
 }
@@ -147,7 +163,7 @@ sgen_set_bridge_implementation (const char *name)
 
        if (selection == BRIDGE_PROCESSOR_INVALID)
                g_warning ("Invalid value for bridge processor implementation, valid values are: 'new', 'old' and 'tarjan'.");
-       else if (bridge_processor.reset_data)
+       else if (bridge_processor_started ())
                g_warning ("Cannot set bridge processor implementation once bridge has already started");
        else
                bridge_processor_selection = selection;
@@ -480,12 +496,9 @@ sgen_bridge_describe_pointer (GCObject *obj)
 static void
 set_dump_prefix (const char *prefix)
 {
-       if (!bridge_processor.set_dump_prefix) {
-               fprintf (stderr, "Warning: Bridge implementation does not support dumping - ignoring.\n");
-               return;
-       }
-
-       bridge_processor.set_dump_prefix (prefix);
+       if (bridge_processor_config.dump_prefix)
+               free (bridge_processor_config.dump_prefix);
+       bridge_processor_config.dump_prefix = strdup (prefix);
 }
 
 /* Test support code */
@@ -652,22 +665,39 @@ register_test_bridge_callbacks (const char *bridge_class_name)
        mono_gc_register_bridge_callbacks (&callbacks);
 }
 
+gboolean
+sgen_bridge_handle_gc_param (const char *opt)
+{
+       g_assert (!bridge_processor_started ());
+
+       if (!strcmp (opt, "bridge-require-precise-merge")) {
+               bridge_processor_config.scc_precise_merge = TRUE;
+       } else {
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
 gboolean
 sgen_bridge_handle_gc_debug (const char *opt)
 {
+       g_assert (!bridge_processor_started ());
+
        if (g_str_has_prefix (opt, "bridge=")) {
                opt = strchr (opt, '=') + 1;
                register_test_bridge_callbacks (g_strdup (opt));
        } else if (!strcmp (opt, "enable-bridge-accounting")) {
-               bridge_processor.enable_accounting ();
+               bridge_processor_config.accounting = TRUE;
        } else if (g_str_has_prefix (opt, "bridge-dump=")) {
                char *prefix = strchr (opt, '=') + 1;
-               set_dump_prefix (prefix);
+               set_dump_prefix(prefix);
        } else if (g_str_has_prefix (opt, "bridge-compare-to=")) {
                const char *name = strchr (opt, '=') + 1;
                BridgeProcessorSelection selection = bridge_processor_name (name);
 
                if (selection != BRIDGE_PROCESSOR_INVALID) {
+                       // Compare processor doesn't get config
                        init_bridge_processor (&compare_to_bridge_processor, selection);
                } else {
                        g_warning ("Invalid bridge implementation to compare against - ignoring.");
index b11df8a17b5e39d83ef82e05e98ca52c5125cf87..a03b0a81bfd508c93bcc82afa65aa3ff6e4ae3da 100644 (file)
@@ -17,8 +17,8 @@
  * When SGen is done marking, it puts together a list of all dead bridged
  * objects.  This is passed to the bridge processor, which does an analysis to
  * simplify the graph: It replaces strongly-connected components with single
- * nodes, and then removes any nodes corresponding to components which do not
- * contain bridged objects.
+ * nodes, and may remove nodes corresponding to components which do not contain
+ * bridged objects.
  *
  * The output of the SCC analysis is passed to the client's `cross_references()`
  * callback.  This consists of 2 arrays, an array of SCCs (MonoGCBridgeSCC),
@@ -54,7 +54,7 @@
 MONO_BEGIN_DECLS
 
 enum {
-       SGEN_BRIDGE_VERSION = 4
+       SGEN_BRIDGE_VERSION = 5
 };
        
 typedef enum {
index 19265f57ef4bf84d41c97a2542253251a0cf2265..c4feb7fa150a82831e45d81a6abd870d995ad25c 100644 (file)
@@ -189,13 +189,13 @@ static MonoMethod *write_barrier_noconc_method;
 gboolean
 sgen_is_critical_method (MonoMethod *method)
 {
-       return (method == write_barrier_conc_method || method == write_barrier_noconc_method || sgen_is_managed_allocator (method));
+       return sgen_is_managed_allocator (method);
 }
 
 gboolean
 sgen_has_critical_method (void)
 {
-       return write_barrier_conc_method || write_barrier_noconc_method || sgen_has_managed_allocator ();
+       return sgen_has_managed_allocator ();
 }
 
 #ifndef DISABLE_JIT
@@ -491,7 +491,7 @@ mono_gc_invoke_finalizers (void)
        return sgen_gc_invoke_finalizers ();
 }
 
-gboolean
+MonoBoolean
 mono_gc_pending_finalizers (void)
 {
        return sgen_have_pending_finalizers ();
@@ -2896,7 +2896,7 @@ sgen_client_handle_gc_param (const char *opt)
        } else if (g_str_has_prefix (opt, "toggleref-test")) {
                /* FIXME: This should probably in MONO_GC_DEBUG */
                sgen_register_test_toggleref_callback ();
-       } else {
+       } else if (!sgen_bridge_handle_gc_param (opt)) {
                return FALSE;
        }
        return TRUE;
index 4631c0c5430f2ec946931fee01fee5ae079a6ad7..501ceb76d5b8c5a987d26b28891e01ca701cdb53 100644 (file)
@@ -101,6 +101,8 @@ typedef struct _SCC {
 #endif
 } SCC;
 
+static char *dump_prefix = NULL;
+
 // Maps managed objects to corresponding HashEntry stricts
 static SgenHashTable hash_table = SGEN_HASH_TABLE_INIT (INTERNAL_MEM_BRIDGE_HASH_TABLE, INTERNAL_MEM_BRIDGE_HASH_TABLE_ENTRY, sizeof (HashEntry), mono_aligned_addr_hash, NULL);
 
@@ -161,11 +163,16 @@ dyn_array_int_contains (DynIntArray *da, int x)
 #endif
 
 static void
-enable_accounting (void)
+set_config (const SgenBridgeProcessorConfig *config)
 {
-       SgenHashTable table = SGEN_HASH_TABLE_INIT (INTERNAL_MEM_BRIDGE_HASH_TABLE, INTERNAL_MEM_BRIDGE_HASH_TABLE_ENTRY, sizeof (HashEntryWithAccounting), mono_aligned_addr_hash, NULL);
-       bridge_accounting_enabled = TRUE;
-       hash_table = table;
+       if (config->accounting) {
+               SgenHashTable table = SGEN_HASH_TABLE_INIT (INTERNAL_MEM_BRIDGE_HASH_TABLE, INTERNAL_MEM_BRIDGE_HASH_TABLE_ENTRY, sizeof (HashEntryWithAccounting), mono_aligned_addr_hash, NULL);
+               bridge_accounting_enabled = TRUE;
+               hash_table = table;
+       }
+       if (config->dump_prefix) {
+               dump_prefix = strdup (config->dump_prefix);
+       }
 }
 
 static MonoGCBridgeObjectKind
@@ -604,8 +611,6 @@ reset_flags (SCC *scc)
 }
 #endif
 
-static char *dump_prefix = NULL;
-
 static void
 dump_graph (void)
 {
@@ -657,12 +662,6 @@ dump_graph (void)
        fclose (file);
 }
 
-static void
-set_dump_prefix (const char *prefix)
-{
-       dump_prefix = strdup (prefix);
-}
-
 static int
 compare_hash_entries (const HashEntry *e1, const HashEntry *e2)
 {
@@ -1087,8 +1086,7 @@ sgen_new_bridge_init (SgenBridgeProcessor *collector)
        collector->class_kind = class_kind;
        collector->register_finalized_object = register_finalized_object;
        collector->describe_pointer = describe_pointer;
-       collector->enable_accounting = enable_accounting;
-       collector->set_dump_prefix = set_dump_prefix;
+       collector->set_config = set_config;
 
        bridge_processor = collector;
 }
index d33d5d86815d795db6168cf97b9e0f24b9c3f1ff..346e4b0aeb50a1aff3d8ada64bf8b2042898dd17 100644 (file)
@@ -372,11 +372,13 @@ dyn_array_int_merge_one (DynIntArray *array, int value)
 
 
 static void
-enable_accounting (void)
+set_config (const SgenBridgeProcessorConfig *config)
 {
-       SgenHashTable table = SGEN_HASH_TABLE_INIT (INTERNAL_MEM_BRIDGE_HASH_TABLE, INTERNAL_MEM_BRIDGE_HASH_TABLE_ENTRY, sizeof (HashEntryWithAccounting), mono_aligned_addr_hash, NULL);
-       bridge_accounting_enabled = TRUE;
-       hash_table = table;
+       if (config->accounting) {
+               SgenHashTable table = SGEN_HASH_TABLE_INIT (INTERNAL_MEM_BRIDGE_HASH_TABLE, INTERNAL_MEM_BRIDGE_HASH_TABLE_ENTRY, sizeof (HashEntryWithAccounting), mono_aligned_addr_hash, NULL);
+               bridge_accounting_enabled = TRUE;
+               hash_table = table;
+       }
 }
 
 static MonoGCBridgeObjectKind
@@ -922,7 +924,7 @@ sgen_old_bridge_init (SgenBridgeProcessor *collector)
        collector->class_kind = class_kind;
        collector->register_finalized_object = register_finalized_object;
        collector->describe_pointer = describe_pointer;
-       collector->enable_accounting = enable_accounting;
+       collector->set_config = set_config;
 
        bridge_processor = collector;
 }
index 90c8266b341f7749da66d0ae7d3fab1a6ebbffcc..32bab7ebcb8655cc6adf94c918beb880ce7a8a72 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include "config.h"
+
 #ifdef HAVE_SGEN_GC
 
 
@@ -65,6 +66,10 @@ mono_gc_get_restart_signal (void)
 {
        return -1;
 }
-
-#endif
+#else
+       #ifdef _MSC_VER
+               // Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+               void __mono_win32_sgen_os_coop_quiet_lnk4221(void) {}
+       #endif
+#endif /* USE_COOP_GC */
 #endif
index ea14448ccfbfaeb7b376fbf06abd59135cf6b680..60e5933450fba844a1888577df232f4255102127 100644 (file)
@@ -209,6 +209,8 @@ sgen_client_stop_world (int generation)
 
        acquire_gc_locks ();
 
+       mono_profiler_gc_event (MONO_GC_EVENT_PRE_STOP_WORLD_LOCKED, generation);
+
        /* We start to scan after locks are taking, this ensures we won't be interrupted. */
        sgen_process_togglerefs ();
 
@@ -283,6 +285,8 @@ sgen_client_restart_world (int generation, gint64 *stw_time)
         */
        release_gc_locks ();
 
+       mono_profiler_gc_event (MONO_GC_EVENT_POST_START_WORLD_UNLOCKED, generation);
+
        *stw_time = usec;
 }
 
index 76c5ac64a90d1380e68f88e5e0f1b44f83a7481c..daa983e64ac61ce1a29d534c4f2785d872e5e3ce 100644 (file)
@@ -19,8 +19,6 @@
 
 #include "sgen/sgen-gc.h"
 #include "sgen-bridge-internals.h"
-#include "sgen/sgen-hash-table.h"
-#include "sgen/sgen-qsort.h"
 #include "tabledefs.h"
 #include "utils/mono-logger-internals.h"
 
  *     which colors. The color graph then becomes the reduced SCC graph.
  */
 
-static void
-enable_accounting (void)
-{
-       // bridge_accounting_enabled = TRUE;
-       // hash_table = (SgenHashTable)SGEN_HASH_TABLE_INIT (INTERNAL_MEM_BRIDGE_HASH_TABLE, INTERNAL_MEM_BRIDGE_HASH_TABLE_ENTRY, sizeof (HashEntryWithAccounting), mono_aligned_addr_hash, NULL);
-}
-
 // Is this class bridged or not, and should its dependencies be scanned or not?
 // The result of this callback will be cached for use by is_opaque_object later.
 static MonoGCBridgeObjectKind
@@ -83,6 +74,36 @@ class_kind (MonoClass *klass)
 //enable usage logging
 // #define DUMP_GRAPH 1
 
+/* Used in bridgeless_color_is_heavy:
+ * The idea here is as long as the reference fanin and fanout on a node are both 2 or greater, then
+ * removing that node will result in a net increase in edge count. So the question is which node
+ * removals are counterproductive (i.e., how many edges saved balances out one node added).
+ * The number of edges saved by preserving a node is (fanin*fanout - fanin - fanout).
+ *
+ * With all that in mind:
+ *
+ * - HEAVY_REFS_MIN is the number that *both* fanin and fanout must meet to preserve the node.
+ * - HEAVY_COMBINED_REFS_MIN is the number (fanin*fanout) must meet to preserve the node.
+ *
+ * Note HEAVY_COMBINED_REFS_MIN must be <= 2*INCOMING_COLORS_MAX, or we won't know the true fanin.
+ */
+
+#define HEAVY_REFS_MIN 2
+#define HEAVY_COMBINED_REFS_MIN 60
+
+/* Used in ColorData:
+ * The higher INCOMING_COLORS_BITS is the higher HEAVY_COMBINED_REFS_MIN can be (see above).
+ * However, API_INDEX_BITS + INCOMING_COLORS_BITS must be equal to 31, and if API_INDEX_BITS is too
+ * low then terrible things will happen if too many colors are generated. (The number of colors we
+ * will ever attempt to generate is currently naturally limited by the JNI GREF limit.)
+ */
+
+#define API_INDEX_BITS        26
+#define INCOMING_COLORS_BITS  5
+
+#define API_INDEX_MAX         ((1<<API_INDEX_BITS)-1)
+#define INCOMING_COLORS_MAX   ((1<<INCOMING_COLORS_BITS)-1)
+
 // ScanData state
 enum {
        INITIAL,
@@ -94,13 +115,17 @@ enum {
 /*
 Optimizations:
        We can split this data structure in two, those with bridges and those without
+       (and only bridgeless need to record incoming_colors)
 */
 typedef struct {
-    // Colors (ColorDatas) linked to by objects with this color
+       // Colors (ColorDatas) linked to by objects with this color
        DynPtrArray other_colors;
-    // Bridge objects (GCObjects) held by objects with this color
+       // Bridge objects (GCObjects) held by objects with this color
        DynPtrArray bridges;
-       int api_index    : 31;
+       // Index of this color's MonoGCBridgeSCC in the array passed to the client (or -1 for none)
+       signed api_index         : API_INDEX_BITS;
+       // Count of colors that list this color in their other_colors
+       unsigned incoming_colors : INCOMING_COLORS_BITS;
        unsigned visited : 1;
 } ColorData;
 
@@ -115,7 +140,7 @@ typedef struct _ScanData {
        // Tarjan algorithm index (order visited)
        int index;
        // Tarjan index of lowest-index object known reachable from here
-       int low_index : 27;
+       signed low_index : 27;
 
        // See "ScanData state" enum above
        unsigned state : 2;
@@ -124,7 +149,22 @@ typedef struct _ScanData {
        unsigned obj_state : 2;
 } ScanData;
 
+/* Should color be made visible to client even though it has no bridges?
+ * True if we predict the number of reduced edges to be enough to justify the extra node.
+ */
+static inline gboolean
+bridgeless_color_is_heavy (ColorData *data) {
+       int fanin = data->incoming_colors;
+       int fanout = dyn_array_ptr_size (&data->other_colors);
+       return fanin > HEAVY_REFS_MIN && fanout > HEAVY_REFS_MIN
+               && fanin*fanout >= HEAVY_COMBINED_REFS_MIN;
+}
 
+// Should color be made visible to client?
+static inline gboolean
+color_visible_to_client (ColorData *data) {
+       return dyn_array_ptr_size (&data->bridges) || bridgeless_color_is_heavy (data);
+}
 
 // Stacks of ScanData objects used for tarjan algorithm.
 // The Tarjan algorithm is normally defined recursively; here scan_stack simulates the call stack of a recursive algorithm,
@@ -134,12 +174,21 @@ static DynPtrArray scan_stack, loop_stack;
 // GCObjects on which register_finalized_object has been called
 static DynPtrArray registered_bridges;
 
-// ColorData objects
+// As we traverse the graph, which ColorData objects are accessible from our current position?
 static DynPtrArray color_merge_array;
+// Running hash of the contents of the color_merge_array.
+static unsigned int color_merge_array_hash;
+
+static void color_merge_array_empty ()
+{
+       dyn_array_ptr_empty (&color_merge_array);
+       color_merge_array_hash = 0;
+}
 
 static int ignored_objects;
 static int object_index;
 static int num_colors_with_bridges;
+static int num_sccs;
 static int xref_count;
 
 static size_t setup_time, tarjan_time, scc_setup_time, gather_xref_time, xref_setup_time, cleanup_time;
@@ -161,6 +210,7 @@ static ObjectBucket *root_object_bucket;
 static ObjectBucket *cur_object_bucket;
 static int object_data_count;
 
+// Arenas to allocate ScanData from
 static ObjectBucket*
 new_object_bucket (void)
 {
@@ -213,7 +263,7 @@ free_object_buckets (void)
 //ColorData buckets
 #define NUM_COLOR_ENTRIES ((BUCKET_SIZE - SIZEOF_VOID_P * 2) / sizeof (ColorData))
 
-// Same as ObjectBucket except NUM_COLOR_ENTRIES and NUM_SCAN_ENTRIES differ
+// Arenas for ColorDatas, same as ObjectBucket except items-per-bucket differs
 typedef struct _ColorBucket ColorBucket;
 struct _ColorBucket {
        ColorBucket *next;
@@ -356,11 +406,13 @@ find_or_create_data (GCObject *obj)
 //----------
 typedef struct {
        ColorData *color;
-       int hash;
+       unsigned int hash;
 } HashEntry;
 
 /*
-We tried 2/32, 2/128, 4/32, 4/128, 6/128 and 8/128.
+The merge cache maps an ordered list of ColorDatas [the color_merge_array] to a single ColorData.
+
+About cache bucket tuning: We tried 2/32, 2/128, 4/32, 4/128, 6/128 and 8/128.
 
 The performance cost between 4/128 and 8/128 is so small since cache movement happens completely in the same cacheline,
 making the extra space pretty much free.
@@ -373,17 +425,39 @@ Memory wise, 4/32 takes 512 and 8/128 takes 8k, so it's quite reasonable.
 #define ELEMENTS_PER_BUCKET 8
 #define COLOR_CACHE_SIZE 128
 static HashEntry merge_cache [COLOR_CACHE_SIZE][ELEMENTS_PER_BUCKET];
+static unsigned int hash_perturb;
+
+// If true, disable an optimization where sometimes SCC nodes are merged without a perfect check
+static gboolean scc_precise_merge;
 
-static int
-mix_hash (size_t hash)
+static unsigned int
+mix_hash (uintptr_t source)
 {
-       return (int)(((hash * 215497) >> 16) ^ ((hash * 1823231) + hash));
+       unsigned int hash = source;
+
+       // The full hash determines whether two colors can be merged-- sometimes exclusively.
+       // This value changes every GC, so XORing it in before performing the hash will make the
+       // chance that two different colors will produce the same hash on successive GCs very low.
+       hash = hash ^ hash_perturb;
+
+       // Actual hash
+       hash = (((hash * 215497) >> 16) ^ ((hash * 1823231) + hash));
+
+       // Mix in highest bits on 64-bit systems only
+       if (sizeof (source) > 4)
+               hash = hash ^ (source >> 32);
+
+       return hash;
 }
 
 static void
 reset_cache (void)
 {
        memset (merge_cache, 0, sizeof (merge_cache));
+
+       // When using the precise merge debug option, we do not want the inconsistency caused by hash_perturb.
+       if (!scc_precise_merge)
+               ++hash_perturb;
 }
 
 
@@ -397,6 +471,13 @@ dyn_array_ptr_contains (DynPtrArray *da, void *x)
        return FALSE;
 }
 
+static gboolean
+match_colors_estimate (DynPtrArray *a, DynPtrArray *b)
+{
+       return dyn_array_ptr_size (a) == dyn_array_ptr_size (b);
+}
+
+
 static gboolean
 match_colors (DynPtrArray *a, DynPtrArray *b)
 {
@@ -411,23 +492,36 @@ match_colors (DynPtrArray *a, DynPtrArray *b)
        return TRUE;
 }
 
-static int cache_hits, cache_misses;
+// If scc_precise_merge, "semihits" refers to find_in_cache calls aborted because the merge array was too large.
+// Otherwise "semihits" refers to cache hits where the match was only estimated.
+static int cache_hits, cache_semihits, cache_misses;
 
+// The cache contains only non-bridged colors.
 static ColorData*
 find_in_cache (int *insert_index)
 {
        HashEntry *bucket;
-       int i, hash, size, index;
+       int i, size, index;
 
        size = dyn_array_ptr_size (&color_merge_array);
-       /* Cache checking is very ineficient with a lot of elements*/
-       if (size > 3)
+
+       /* Color equality checking is very expensive with a lot of elements, so when there are many
+        * elements we switch to a cheap comparison method which allows false positives. When false
+        * positives occur the worst that can happen is two items will be inappropriately merged
+        * and memory will be retained longer than it should be. We assume that will correct itself
+        * on the next GC (the hash_perturb mechanism increases the probability of this).
+        *
+        * Because this has *some* potential to create problems, if the user set the debug option
+        * 'enable-tarjan-precise-merge' we bail out early (and never merge SCCs with >3 colors).
+        */
+       gboolean color_merge_array_large = size > 3;
+       if (scc_precise_merge && color_merge_array_large) {
+               ++cache_semihits;
                return NULL;
+       }
 
-       hash = 0;
-       for (i = 0 ; i < size; ++i)
-               hash += mix_hash ((size_t)dyn_array_ptr_get (&color_merge_array, i));
-       if (!hash)
+       unsigned int hash = color_merge_array_hash;
+       if (!hash) // 0 is used to indicate an empty bucket entry
                hash = 1;
 
        index = hash & (COLOR_CACHE_SIZE - 1);
@@ -435,9 +529,17 @@ find_in_cache (int *insert_index)
        for (i = 0; i < ELEMENTS_PER_BUCKET; ++i) {
                if (bucket [i].hash != hash)
                        continue;
-               if (match_colors (&bucket [i].color->other_colors, &color_merge_array)) {
-                       ++cache_hits;
-                       return bucket [i].color;
+
+               if (color_merge_array_large) {
+                       if (match_colors_estimate (&bucket [i].color->other_colors, &color_merge_array)) {
+                               ++cache_semihits;
+                               return bucket [i].color;
+                       }
+               } else {
+                       if (match_colors (&bucket [i].color->other_colors, &color_merge_array)) {
+                               ++cache_hits;
+                               return bucket [i].color;
+                       }
                }
        }
 
@@ -450,14 +552,16 @@ find_in_cache (int *insert_index)
        return NULL;
 }
 
+// A color is needed for an SCC. If the SCC has bridges, the color MUST be newly allocated.
+// If the SCC lacks bridges, the allocator MAY use the cache to merge it with an existing one.
 static ColorData*
-new_color (gboolean force_new)
+new_color (gboolean has_bridges)
 {
-       int i = -1;
+       int cacheSlot = -1;
        ColorData *cd;
        /* XXX Try to find an equal one and return it */
-       if (!force_new) {
-               cd = find_in_cache (&i);
+       if (!has_bridges) {
+               cd = find_in_cache (&cacheSlot);
                if (cd)
                        return cd;
        }
@@ -465,9 +569,16 @@ new_color (gboolean force_new)
        cd = alloc_color_data ();
        cd->api_index = -1;
        dyn_array_ptr_set_all (&cd->other_colors, &color_merge_array);
-       /* if i >= 0, it means we prepared a given slot to receive the new color */
-       if (i >= 0)
-               merge_cache [i][0].color = cd;
+
+       // Inform targets
+       for (int i = 0; i < dyn_array_ptr_size (&color_merge_array); ++i) {
+               ColorData *points_to = (ColorData *)dyn_array_ptr_get (&color_merge_array, i);
+               points_to->incoming_colors = MIN (points_to->incoming_colors + 1, INCOMING_COLORS_MAX);
+       }
+
+       /* if cacheSlot >= 0, it means we prepared a given slot to receive the new color */
+       if (cacheSlot >= 0)
+               merge_cache [cacheSlot][0].color = cd;
 
        return cd;
 }
@@ -587,6 +698,7 @@ compute_low_index (ScanData *data, GCObject *obj)
 
        cd = other->color;
        if (!cd->visited) {
+               color_merge_array_hash += mix_hash ((uintptr_t) other->color);
                dyn_array_ptr_add (&color_merge_array, other->color);
                cd->visited = TRUE;
        }
@@ -608,16 +720,24 @@ compute_low (ScanData *data)
        #include "sgen/sgen-scan-object.h"
 }
 
+// A non-bridged object needs a single color describing the current merge array.
 static ColorData*
 reduce_color (void)
 {
        ColorData *color = NULL;
        int size = dyn_array_ptr_size (&color_merge_array);
 
+       // Merge array is empty-- this SCC points to no bridged colors.
+       // This SCC can be ignored completely.
        if (size == 0)
                color = NULL;
+
+       // Merge array has one item-- this SCC points to a single bridged color.
+       // This SCC can be forwarded to the pointed-to color.
        else if (size == 1) {
                color = (ColorData *)dyn_array_ptr_get (&color_merge_array, 0);
+
+       // This SCC gets to talk to the color allocator.
        } else
                color = new_color (FALSE);
 
@@ -694,7 +814,7 @@ create_scc (ScanData *data)
                g_assert (cd->visited);
                cd->visited = FALSE;
        }
-       dyn_array_ptr_empty (&color_merge_array);
+       color_merge_array_empty ();
        found_bridge = FALSE;
 }
 
@@ -704,7 +824,7 @@ dfs (void)
        g_assert (dyn_array_ptr_size (&scan_stack) == 1);
        g_assert (dyn_array_ptr_size (&loop_stack) == 0);
 
-       dyn_array_ptr_empty (&color_merge_array);
+       color_merge_array_empty ();
 
        while (dyn_array_ptr_size (&scan_stack) > 0) {
                ScanData *data = (ScanData *)dyn_array_ptr_pop (&scan_stack);
@@ -891,7 +1011,7 @@ gather_xrefs (ColorData *color)
                if (src->visited)
                        continue;
                src->visited = TRUE;
-               if (dyn_array_ptr_size (&src->bridges))
+               if (color_visible_to_client (src))
                        dyn_array_ptr_add (&color_merge_array, src);
                else
                        gather_xrefs (src);
@@ -907,7 +1027,7 @@ reset_xrefs (ColorData *color)
                if (!src->visited)
                        continue;
                src->visited = FALSE;
-               if (!dyn_array_ptr_size (&src->bridges))
+               if (!color_visible_to_client (src))
                        reset_xrefs (src);
        }
 }
@@ -915,9 +1035,7 @@ reset_xrefs (ColorData *color)
 static void
 processing_build_callback_data (int generation)
 {
-       int j, api_index;
-       MonoGCBridgeSCC **api_sccs;
-       MonoGCBridgeXRef *api_xrefs;
+       int j;
        gint64 curtime;
        ColorBucket *cur;
 
@@ -936,15 +1054,27 @@ processing_build_callback_data (int generation)
        printf ("number of SCCs %d\n", num_colors_with_bridges);
 #endif
 
+       // Count the number of SCCs visible to the client
+       num_sccs = 0;
+       for (cur = root_color_bucket; cur; cur = cur->next) {
+               ColorData *cd;
+               for (cd = &cur->data [0]; cd < cur->next_data; ++cd) {
+                       if (color_visible_to_client (cd))
+                               num_sccs++;
+               }
+       }
+
        /* This is a straightforward translation from colors to the bridge callback format. */
-       api_sccs = (MonoGCBridgeSCC **)sgen_alloc_internal_dynamic (sizeof (MonoGCBridgeSCC*) * num_colors_with_bridges, INTERNAL_MEM_BRIDGE_DATA, TRUE);
-       api_index = xref_count = 0;
+       MonoGCBridgeSCC **api_sccs = (MonoGCBridgeSCC **)sgen_alloc_internal_dynamic (sizeof (MonoGCBridgeSCC*) * num_sccs, INTERNAL_MEM_BRIDGE_DATA, TRUE);
+       int api_index = 0;
+       xref_count = 0;
 
+       // Convert visible SCCs, along with their bridged object list, to MonoGCBridgeSCCs in the client's SCC list
        for (cur = root_color_bucket; cur; cur = cur->next) {
                ColorData *cd;
                for (cd = &cur->data [0]; cd < cur->next_data; ++cd) {
                        int bridges = dyn_array_ptr_size (&cd->bridges);
-                       if (!bridges)
+                       if (!(bridges || bridgeless_color_is_heavy (cd)))
                                continue;
 
                        api_sccs [api_index] = (MonoGCBridgeSCC *)sgen_alloc_internal_dynamic (sizeof (MonoGCBridgeSCC) + sizeof (MonoObject*) * bridges, INTERNAL_MEM_BRIDGE_DATA, TRUE);
@@ -955,20 +1085,22 @@ processing_build_callback_data (int generation)
 
                        for (j = 0; j < bridges; ++j)
                                api_sccs [api_index]->objs [j] = (MonoObject *)dyn_array_ptr_get (&cd->bridges, j);
+
+                       g_assert(api_index < API_INDEX_MAX);
                        api_index++;
                }
        }
 
        scc_setup_time = step_timer (&curtime);
 
+       // Eliminate non-visible SCCs from the SCC list and redistribute xrefs
        for (cur = root_color_bucket; cur; cur = cur->next) {
                ColorData *cd;
                for (cd = &cur->data [0]; cd < cur->next_data; ++cd) {
-                       int bridges = dyn_array_ptr_size (&cd->bridges);
-                       if (!bridges)
+                       if (!color_visible_to_client (cd))
                                continue;
 
-                       dyn_array_ptr_empty (&color_merge_array);
+                       color_merge_array_empty ();
                        gather_xrefs (cd);
                        reset_xrefs (cd);
                        dyn_array_ptr_set_all (&cd->other_colors, &color_merge_array);
@@ -983,27 +1115,28 @@ processing_build_callback_data (int generation)
        dump_color_table (" after xref pass", TRUE);
 #endif
 
-       api_xrefs = (MonoGCBridgeXRef *)sgen_alloc_internal_dynamic (sizeof (MonoGCBridgeXRef) * xref_count, INTERNAL_MEM_BRIDGE_DATA, TRUE);
-       api_index = 0;
+       // Write out xrefs array
+       MonoGCBridgeXRef *api_xrefs = (MonoGCBridgeXRef *)sgen_alloc_internal_dynamic (sizeof (MonoGCBridgeXRef) * xref_count, INTERNAL_MEM_BRIDGE_DATA, TRUE);
+       int xref_index = 0;
        for (cur = root_color_bucket; cur; cur = cur->next) {
                ColorData *src;
                for (src = &cur->data [0]; src < cur->next_data; ++src) {
-                       int bridges = dyn_array_ptr_size (&src->bridges);
-                       if (!bridges)
+                       if (!color_visible_to_client (src))
                                continue;
 
                        for (j = 0; j < dyn_array_ptr_size (&src->other_colors); ++j) {
                                ColorData *dest = (ColorData *)dyn_array_ptr_get (&src->other_colors, j);
-                               g_assert (dyn_array_ptr_size (&dest->bridges)); /* We flattened the color graph, so this must never happen. */
+                               g_assert (color_visible_to_client (dest)); /* Supposedly we already eliminated all xrefs to non-visible objects. */
+
+                               api_xrefs [xref_index].src_scc_index = src->api_index;
+                               api_xrefs [xref_index].dst_scc_index = dest->api_index;
 
-                               api_xrefs [api_index].src_scc_index = src->api_index;
-                               api_xrefs [api_index].dst_scc_index = dest->api_index;
-                               ++api_index;
+                               ++xref_index;
                        }
                }
        }
 
-       g_assert (xref_count == api_index);
+       g_assert (xref_count == xref_index);
        xref_setup_time = step_timer (&curtime);
 
 #if defined (DUMP_GRAPH)
@@ -1013,7 +1146,7 @@ processing_build_callback_data (int generation)
 #endif
 
        //FIXME move half of the cleanup to before the bridge callback?
-       bridge_processor->num_sccs = num_colors_with_bridges;
+       bridge_processor->num_sccs = num_sccs;
        bridge_processor->api_sccs = api_sccs;
        bridge_processor->num_xrefs = xref_count;
        bridge_processor->api_xrefs = api_xrefs;
@@ -1026,7 +1159,7 @@ processing_after_callback (int generation)
        int bridge_count = dyn_array_ptr_size (&registered_bridges);
        int object_count = object_data_count;
        int color_count = color_data_count;
-       int scc_count = num_colors_with_bridges;
+       int colors_with_bridges_count = num_colors_with_bridges;
 
        SGEN_TV_GETTIME (curtime);
 
@@ -1035,10 +1168,10 @@ processing_after_callback (int generation)
 
        cleanup_time = step_timer (&curtime);
 
-       mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_GC, "GC_TAR_BRIDGE bridges %d objects %d colors %d ignored %d sccs %d xref %d cache %d/%d setup %.2fms tarjan %.2fms scc-setup %.2fms gather-xref %.2fms xref-setup %.2fms cleanup %.2fms",
-               bridge_count, object_count, color_count,
-               ignored_objects, scc_count, xref_count,
-               cache_hits, cache_misses,
+       mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_GC, "GC_TAR_BRIDGE bridges %d objects %d opaque %d colors %d colors-bridged %d colors-visible %d xref %d cache-hit %d cache-%s %d cache-miss %d setup %.2fms tarjan %.2fms scc-setup %.2fms gather-xref %.2fms xref-setup %.2fms cleanup %.2fms",
+               bridge_count, object_count, ignored_objects,
+               color_count, colors_with_bridges_count, num_sccs, xref_count,
+               cache_hits, (scc_precise_merge ? "abstain" : "semihit"), cache_semihits, cache_misses,
                setup_time / 10000.0f,
                tarjan_time / 10000.0f,
                scc_setup_time / 10000.0f,
@@ -1046,7 +1179,7 @@ processing_after_callback (int generation)
                xref_setup_time / 10000.0f,
                cleanup_time / 10000.0f);
 
-       cache_hits = cache_misses = 0;
+       cache_hits = cache_semihits = cache_misses = 0;
        ignored_objects = 0;
 }
 
@@ -1072,6 +1205,15 @@ describe_pointer (GCObject *obj)
        // printf ("  is visited: %d\n", (int)entry->is_visited);
 }
 
+static void
+set_config (const SgenBridgeProcessorConfig *config)
+{
+       if (config->scc_precise_merge) {
+               hash_perturb = 0;
+               scc_precise_merge = TRUE;
+       }
+}
+
 void
 sgen_tarjan_bridge_init (SgenBridgeProcessor *collector)
 {
@@ -1082,12 +1224,12 @@ sgen_tarjan_bridge_init (SgenBridgeProcessor *collector)
        collector->class_kind = class_kind;
        collector->register_finalized_object = register_finalized_object;
        collector->describe_pointer = describe_pointer;
-       collector->enable_accounting = enable_accounting;
-       // collector->set_dump_prefix = set_dump_prefix;
+       collector->set_config = set_config;
 
        sgen_register_fixed_internal_mem_type (INTERNAL_MEM_TARJAN_OBJ_BUCKET, BUCKET_SIZE);
        g_assert (sizeof (ObjectBucket) <= BUCKET_SIZE);
        g_assert (sizeof (ColorBucket) <= BUCKET_SIZE);
+       g_assert (API_INDEX_BITS + INCOMING_COLORS_BITS <= 31);
        bridge_processor = collector;
 }
 
index 04c55e7241bc4a85ced64fc6cf8bfbc3ae11a192..d4d168da76691a76c3f041b40cf2c45dde95d775 100644 (file)
@@ -774,16 +774,15 @@ ves_icall_System_Net_Sockets_Socket_Accept_internal (SOCKET sock, gint32 *werror
 
        MONO_EXIT_GC_SAFE;
 
+       if (newsock == INVALID_SOCKET)
+               *werror = WSAGetLastError ();
+
        mono_thread_info_uninstall_interrupt (&interrupted);
-       if (interrupted) {
+       if (interrupted)
                *werror = WSAEINTR;
-               return NULL;
-       }
 
-       if (newsock == INVALID_SOCKET) {
-               *werror = WSAGetLastError ();
+       if (*werror)
                return NULL;
-       }
        
        return GUINT_TO_POINTER (newsock);
 }
@@ -1336,15 +1335,13 @@ ves_icall_System_Net_Sockets_Socket_Connect_internal (SOCKET sock, MonoObject *s
 
        MONO_EXIT_GC_SAFE;
 
-       mono_thread_info_uninstall_interrupt (&interrupted);
-       if (interrupted) {
-               *werror = WSAEINTR;
-               return;
-       }
-
        if (ret == SOCKET_ERROR)
                *werror = WSAGetLastError ();
 
+       mono_thread_info_uninstall_interrupt (&interrupted);
+       if (interrupted)
+               *werror = WSAEINTR;
+
        g_free (sa);
 }
 
@@ -1423,10 +1420,10 @@ ves_icall_System_Net_Sockets_Socket_Disconnect_internal (SOCKET sock, MonoBoolea
        MONO_ENTER_GC_SAFE;
 
        if (_wapi_disconnectex != NULL) {
-               if (!_wapi_disconnectex (sock, NULL, TF_REUSE_SOCKET, 0))
+               if (!_wapi_disconnectex (sock, NULL, reuse ? TF_REUSE_SOCKET : 0, 0))
                        *werror = WSAGetLastError ();
        } else if (_wapi_transmitfile != NULL) {
-               if (!_wapi_transmitfile (sock, NULL, 0, 0, NULL, NULL, TF_DISCONNECT | TF_REUSE_SOCKET))
+               if (!_wapi_transmitfile (sock, NULL, 0, 0, NULL, NULL, TF_DISCONNECT | (reuse ? TF_REUSE_SOCKET : 0)))
                        *werror = WSAGetLastError ();
        } else {
                *werror = ERROR_NOT_SUPPORTED;
@@ -1481,16 +1478,15 @@ ves_icall_System_Net_Sockets_Socket_Receive_internal (SOCKET sock, MonoArray *bu
 
        MONO_EXIT_GC_SAFE;
 
+       if (ret == SOCKET_ERROR)
+               *werror = WSAGetLastError ();
+
        mono_thread_info_uninstall_interrupt (&interrupted);
-       if (interrupted) {
+       if (interrupted)
                *werror = WSAEINTR;
-               return 0;
-       }
 
-       if (ret == SOCKET_ERROR) {
-               *werror = WSAGetLastError ();
+       if (*werror)
                return 0;
-       }
 
        return ret;
 }
@@ -1527,16 +1523,15 @@ ves_icall_System_Net_Sockets_Socket_Receive_array_internal (SOCKET sock, MonoArr
 
        MONO_EXIT_GC_SAFE;
 
+       if (ret == SOCKET_ERROR)
+               *werror = WSAGetLastError ();
+
        mono_thread_info_uninstall_interrupt (&interrupted);
-       if (interrupted) {
+       if (interrupted)
                *werror = WSAEINTR;
-               return 0;
-       }
 
-       if (ret == SOCKET_ERROR) {
-               *werror = WSAGetLastError ();
+       if (*werror)
                return 0;
-       }
 
        return recv;
 }
@@ -1588,16 +1583,16 @@ ves_icall_System_Net_Sockets_Socket_ReceiveFrom_internal (SOCKET sock, MonoArray
 
        MONO_EXIT_GC_SAFE;
 
+       if (ret == SOCKET_ERROR)
+               *werror = WSAGetLastError ();
+
        mono_thread_info_uninstall_interrupt (&interrupted);
-       if (interrupted) {
-               g_free (sa);
+
+       if (interrupted)
                *werror = WSAEINTR;
-               return 0;
-       }
 
-       if (ret==SOCKET_ERROR) {
-               g_free (sa);
-               *werror = WSAGetLastError ();
+       if (*werror) {
+               g_free(sa);
                return 0;
        }
 
@@ -1660,16 +1655,15 @@ ves_icall_System_Net_Sockets_Socket_Send_internal (SOCKET sock, MonoArray *buffe
 
        MONO_EXIT_GC_SAFE;
 
+       if (ret == SOCKET_ERROR)
+               *werror = WSAGetLastError ();
+
        mono_thread_info_uninstall_interrupt (&interrupted);
-       if (interrupted) {
+       if (interrupted)
                *werror = WSAEINTR;
-               return 0;
-       }
 
-       if (ret == SOCKET_ERROR) {
-               *werror = WSAGetLastError ();
+       if (*werror)
                return 0;
-       }
 
        return ret;
 }
@@ -1706,17 +1700,16 @@ ves_icall_System_Net_Sockets_Socket_Send_array_internal (SOCKET sock, MonoArray
 
        MONO_EXIT_GC_SAFE;
 
+       if (ret == SOCKET_ERROR)
+               *werror = WSAGetLastError ();
+
        mono_thread_info_uninstall_interrupt (&interrupted);
-       if (interrupted) {
+       if (interrupted)
                *werror = WSAEINTR;
-               return 0;
-       }
 
-       if (ret == SOCKET_ERROR) {
-               *werror = WSAGetLastError ();
+       if (*werror)
                return 0;
-       }
-       
+
        return sent;
 }
 
@@ -1773,18 +1766,18 @@ ves_icall_System_Net_Sockets_Socket_SendTo_internal (SOCKET sock, MonoArray *buf
 
        MONO_EXIT_GC_SAFE;
 
+       if (ret == SOCKET_ERROR)
+               *werror = WSAGetLastError ();
+
        mono_thread_info_uninstall_interrupt (&interrupted);
-       if (interrupted) {
-               g_free (sa);
+       if (interrupted)
                *werror = WSAEINTR;
-               return 0;
-       }
 
-       if (ret == SOCKET_ERROR)
-               *werror = WSAGetLastError ();
+       g_free(sa);
+
+       if (*werror)
+               return 0;
 
-       g_free (sa);
-       
        return ret;
 }
 
@@ -1961,7 +1954,7 @@ ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal (SOCKET sock, g
        int system_level = 0;
        int system_name = 0;
        int ret;
-       int val;
+       int val = 0;
        socklen_t valsize = sizeof (val);
        struct linger linger;
        socklen_t lingersize = sizeof (linger);
@@ -2454,14 +2447,14 @@ ves_icall_System_Net_Sockets_Socket_Shutdown_internal (SOCKET sock, gint32 how,
 
        MONO_EXIT_GC_SAFE;
 
+       if (ret == SOCKET_ERROR)
+               *werror = WSAGetLastError ();
+
        mono_thread_info_uninstall_interrupt (&interrupted);
        if (interrupted) {
                *werror = WSAEINTR;
-               return;
        }
 
-       if (ret == SOCKET_ERROR)
-               *werror = WSAGetLastError ();
 }
 
 gint
diff --git a/mono/metadata/sre-encode.c b/mono/metadata/sre-encode.c
new file mode 100644 (file)
index 0000000..ef91c85
--- /dev/null
@@ -0,0 +1,1303 @@
+/*
+ * sre-encode.c: Routines for encoding SRE builders into a
+ *    MonoDynamicImage and generating tokens.
+ *   
+ * 
+ * Author:
+ *   Paolo Molaro (lupus@ximian.com)
+ *
+ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
+ * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
+ * Copyright 2011 Rodrigo Kumpera
+ * 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>
+
+#include "mono/metadata/dynamic-image-internals.h"
+#include "mono/metadata/dynamic-stream-internals.h"
+#include "mono/metadata/object-internals.h"
+#include "mono/metadata/sre-internals.h"
+#include "mono/metadata/tabledefs.h"
+#include "mono/metadata/tokentype.h"
+#include "mono/utils/checked-build.h"
+
+typedef struct {
+       char *p;
+       char *buf;
+       char *end;
+} SigBuffer;
+
+static guint32 create_typespec (MonoDynamicImage *assembly, MonoType *type);
+static void    encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf);
+static guint32 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type);
+
+#define mono_type_array_get_and_resolve(array, index, error) mono_reflection_type_get_handle ((MonoReflectionType*)mono_array_get (array, gpointer, index), error)
+
+static guint32
+mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
+{
+       return mono_dynstream_add_data (stream, data, len);
+}
+
+static void
+alloc_table (MonoDynamicTable *table, guint nrows)
+{
+       mono_dynimage_alloc_table (table, nrows);
+}
+
+static void
+sigbuffer_init (SigBuffer *buf, int size)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       buf->buf = (char *)g_malloc (size);
+       buf->p = buf->buf;
+       buf->end = buf->buf + size;
+}
+
+static void
+sigbuffer_make_room (SigBuffer *buf, int size)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       if (buf->end - buf->p < size) {
+               int new_size = buf->end - buf->buf + size + 32;
+               char *p = (char *)g_realloc (buf->buf, new_size);
+               size = buf->p - buf->buf;
+               buf->buf = p;
+               buf->p = p + size;
+               buf->end = buf->buf + new_size;
+       }
+}
+
+static void
+sigbuffer_add_value (SigBuffer *buf, guint32 val)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       sigbuffer_make_room (buf, 6);
+       mono_metadata_encode_value (val, buf->p, &buf->p);
+}
+
+static void
+sigbuffer_add_byte (SigBuffer *buf, guint8 val)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       sigbuffer_make_room (buf, 1);
+       buf->p [0] = val;
+       buf->p++;
+}
+
+static void
+sigbuffer_add_mem (SigBuffer *buf, char *p, guint32 size)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       sigbuffer_make_room (buf, size);
+       memcpy (buf->p, p, size);
+       buf->p += size;
+}
+
+static void
+sigbuffer_free (SigBuffer *buf)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       g_free (buf->buf);
+}
+
+static guint32
+sigbuffer_add_to_blob_cached (MonoDynamicImage *assembly, SigBuffer *buf)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       char blob_size [8];
+       char *b = blob_size;
+       guint32 size = buf->p - buf->buf;
+       /* store length */
+       g_assert (size <= (buf->end - buf->buf));
+       mono_metadata_encode_value (size, b, &b);
+       return mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, buf->buf, size);
+}
+
+
+static void
+encode_generic_class (MonoDynamicImage *assembly, MonoGenericClass *gclass, SigBuffer *buf)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       int i;
+       MonoGenericInst *class_inst;
+       MonoClass *klass;
+
+       g_assert (gclass);
+
+       class_inst = gclass->context.class_inst;
+
+       sigbuffer_add_value (buf, MONO_TYPE_GENERICINST);
+       klass = gclass->container_class;
+       sigbuffer_add_value (buf, klass->byval_arg.type);
+       sigbuffer_add_value (buf, mono_dynimage_encode_typedef_or_ref_full (assembly, &klass->byval_arg, FALSE));
+
+       sigbuffer_add_value (buf, class_inst->type_argc);
+       for (i = 0; i < class_inst->type_argc; ++i)
+               encode_type (assembly, class_inst->type_argv [i], buf);
+
+}
+
+static void
+encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       if (!type) {
+               g_assert_not_reached ();
+               return;
+       }
+               
+       if (type->byref)
+               sigbuffer_add_value (buf, MONO_TYPE_BYREF);
+
+       switch (type->type){
+       case MONO_TYPE_VOID:
+       case MONO_TYPE_BOOLEAN:
+       case MONO_TYPE_CHAR:
+       case MONO_TYPE_I1:
+       case MONO_TYPE_U1:
+       case MONO_TYPE_I2:
+       case MONO_TYPE_U2:
+       case MONO_TYPE_I4:
+       case MONO_TYPE_U4:
+       case MONO_TYPE_I8:
+       case MONO_TYPE_U8:
+       case MONO_TYPE_R4:
+       case MONO_TYPE_R8:
+       case MONO_TYPE_I:
+       case MONO_TYPE_U:
+       case MONO_TYPE_STRING:
+       case MONO_TYPE_OBJECT:
+       case MONO_TYPE_TYPEDBYREF:
+               sigbuffer_add_value (buf, type->type);
+               break;
+       case MONO_TYPE_PTR:
+               sigbuffer_add_value (buf, type->type);
+               encode_type (assembly, type->data.type, buf);
+               break;
+       case MONO_TYPE_SZARRAY:
+               sigbuffer_add_value (buf, type->type);
+               encode_type (assembly, &type->data.klass->byval_arg, buf);
+               break;
+       case MONO_TYPE_VALUETYPE:
+       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);
+                       encode_generic_class (assembly, gclass, buf);
+               } else {
+                       /*
+                        * Make sure we use the correct type.
+                        */
+                       sigbuffer_add_value (buf, k->byval_arg.type);
+                       /*
+                        * ensure only non-byref gets passed to mono_image_typedef_or_ref(),
+                        * otherwise two typerefs could point to the same type, leading to
+                        * verification errors.
+                        */
+                       sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, &k->byval_arg));
+               }
+               break;
+       }
+       case MONO_TYPE_ARRAY:
+               sigbuffer_add_value (buf, type->type);
+               encode_type (assembly, &type->data.array->eklass->byval_arg, buf);
+               sigbuffer_add_value (buf, type->data.array->rank);
+               sigbuffer_add_value (buf, 0); /* FIXME: set to 0 for now */
+               sigbuffer_add_value (buf, 0);
+               break;
+       case MONO_TYPE_GENERICINST:
+               encode_generic_class (assembly, type->data.generic_class, buf);
+               break;
+       case MONO_TYPE_VAR:
+       case MONO_TYPE_MVAR:
+               sigbuffer_add_value (buf, type->type);
+               sigbuffer_add_value (buf, mono_type_get_generic_param_num (type));
+               break;
+       default:
+               g_error ("need to encode type %x", type->type);
+       }
+}
+
+static void
+encode_reflection_type (MonoDynamicImage *assembly, MonoReflectionType *type, SigBuffer *buf, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       mono_error_init (error);
+
+       if (!type) {
+               sigbuffer_add_value (buf, MONO_TYPE_VOID);
+               return;
+       }
+
+       MonoType *t = mono_reflection_type_get_handle (type, error);
+       return_if_nok (error);
+       encode_type (assembly, t, buf);
+}
+
+static void
+encode_custom_modifiers (MonoDynamicImage *assembly, MonoArray *modreq, MonoArray *modopt, SigBuffer *buf, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       int i;
+
+       mono_error_init (error);
+
+       if (modreq) {
+               for (i = 0; i < mono_array_length (modreq); ++i) {
+                       MonoType *mod = mono_type_array_get_and_resolve (modreq, i, error);
+                       return_if_nok (error);
+                       sigbuffer_add_byte (buf, MONO_TYPE_CMOD_REQD);
+                       sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod));
+               }
+       }
+       if (modopt) {
+               for (i = 0; i < mono_array_length (modopt); ++i) {
+                       MonoType *mod = mono_type_array_get_and_resolve (modopt, i, error);
+                       return_if_nok (error);
+                       sigbuffer_add_byte (buf, MONO_TYPE_CMOD_OPT);
+                       sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod));
+               }
+       }
+}
+
+#ifndef DISABLE_REFLECTION_EMIT
+guint32
+mono_dynimage_encode_method_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       SigBuffer buf;
+       int i;
+       guint32 nparams =  sig->param_count;
+       guint32 idx;
+
+       if (!assembly->save)
+               return 0;
+
+       sigbuffer_init (&buf, 32);
+       /*
+        * FIXME: vararg, explicit_this, differenc call_conv values...
+        */
+       idx = sig->call_convention;
+       if (sig->hasthis)
+               idx |= 0x20; /* hasthis */
+       if (sig->generic_param_count)
+               idx |= 0x10; /* generic */
+       sigbuffer_add_byte (&buf, idx);
+       if (sig->generic_param_count)
+               sigbuffer_add_value (&buf, sig->generic_param_count);
+       sigbuffer_add_value (&buf, nparams);
+       encode_type (assembly, sig->ret, &buf);
+       for (i = 0; i < nparams; ++i) {
+               if (i == sig->sentinelpos)
+                       sigbuffer_add_byte (&buf, MONO_TYPE_SENTINEL);
+               encode_type (assembly, sig->params [i], &buf);
+       }
+       idx = sigbuffer_add_to_blob_cached (assembly, &buf);
+       sigbuffer_free (&buf);
+       return idx;
+}
+#else /* DISABLE_REFLECTION_EMIT */
+guint32
+mono_dynimage_encode_method_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
+{
+       g_assert_not_reached ();
+       return 0;
+}
+#endif
+
+guint32
+mono_dynimage_encode_method_builder_signature (MonoDynamicImage *assembly, ReflectionMethodBuilder *mb, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       mono_error_init (error);
+
+       /*
+        * FIXME: reuse code from method_encode_signature().
+        */
+       SigBuffer buf;
+       int i;
+       guint32 nparams =  mb->parameters ? mono_array_length (mb->parameters): 0;
+       guint32 ngparams = mb->generic_params ? mono_array_length (mb->generic_params): 0;
+       guint32 notypes = mb->opt_types ? mono_array_length (mb->opt_types): 0;
+       guint32 idx;
+
+       sigbuffer_init (&buf, 32);
+       /* LAMESPEC: all the call conv spec is foobared */
+       idx = mb->call_conv & 0x60; /* has-this, explicit-this */
+       if (mb->call_conv & 2)
+               idx |= 0x5; /* vararg */
+       if (!(mb->attrs & METHOD_ATTRIBUTE_STATIC))
+               idx |= 0x20; /* hasthis */
+       if (ngparams)
+               idx |= 0x10; /* generic */
+       sigbuffer_add_byte (&buf, idx);
+       if (ngparams)
+               sigbuffer_add_value (&buf, ngparams);
+       sigbuffer_add_value (&buf, nparams + notypes);
+       encode_custom_modifiers (assembly, mb->return_modreq, mb->return_modopt, &buf, error);
+       if (!is_ok (error))
+               goto leave;
+       encode_reflection_type (assembly, mb->rtype, &buf, error);
+       if (!is_ok (error))
+               goto leave;
+       for (i = 0; i < nparams; ++i) {
+               MonoArray *modreq = NULL;
+               MonoArray *modopt = NULL;
+               MonoReflectionType *pt;
+
+               if (mb->param_modreq && (i < mono_array_length (mb->param_modreq)))
+                       modreq = mono_array_get (mb->param_modreq, MonoArray*, i);
+               if (mb->param_modopt && (i < mono_array_length (mb->param_modopt)))
+                       modopt = mono_array_get (mb->param_modopt, MonoArray*, i);
+               encode_custom_modifiers (assembly, modreq, modopt, &buf, error);
+               if (!is_ok (error))
+                       goto leave;
+               pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
+               encode_reflection_type (assembly, pt, &buf, error);
+               if (!is_ok (error))
+                       goto leave;
+       }
+       if (notypes)
+               sigbuffer_add_byte (&buf, MONO_TYPE_SENTINEL);
+       for (i = 0; i < notypes; ++i) {
+               MonoReflectionType *pt;
+
+               pt = mono_array_get (mb->opt_types, MonoReflectionType*, i);
+               encode_reflection_type (assembly, pt, &buf, error);
+               if (!is_ok (error))
+                       goto leave;
+       }
+
+       idx = sigbuffer_add_to_blob_cached (assembly, &buf);
+leave:
+       sigbuffer_free (&buf);
+       return idx;
+}
+
+guint32
+mono_dynimage_encode_locals (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       mono_error_init (error);
+
+       MonoDynamicTable *table;
+       guint32 *values;
+       guint32 idx, sig_idx;
+       guint nl = mono_array_length (ilgen->locals);
+       SigBuffer buf;
+       int i;
+
+       sigbuffer_init (&buf, 32);
+       sigbuffer_add_value (&buf, 0x07);
+       sigbuffer_add_value (&buf, nl);
+       for (i = 0; i < nl; ++i) {
+               MonoReflectionLocalBuilder *lb = mono_array_get (ilgen->locals, MonoReflectionLocalBuilder*, i);
+               
+               if (lb->is_pinned)
+                       sigbuffer_add_value (&buf, MONO_TYPE_PINNED);
+               
+               encode_reflection_type (assembly, (MonoReflectionType*)lb->type, &buf, error);
+               if (!is_ok (error)) {
+                       sigbuffer_free (&buf);
+                       return 0;
+               }
+       }
+       sig_idx = sigbuffer_add_to_blob_cached (assembly, &buf);
+       sigbuffer_free (&buf);
+
+       if (assembly->standalonesig_cache == NULL)
+               assembly->standalonesig_cache = g_hash_table_new (NULL, NULL);
+       idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->standalonesig_cache, GUINT_TO_POINTER (sig_idx)));
+       if (idx)
+               return idx;
+
+       table = &assembly->tables [MONO_TABLE_STANDALONESIG];
+       idx = table->next_idx ++;
+       table->rows ++;
+       alloc_table (table, table->rows);
+       values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
+
+       values [MONO_STAND_ALONE_SIGNATURE] = sig_idx;
+
+       g_hash_table_insert (assembly->standalonesig_cache, GUINT_TO_POINTER (sig_idx), GUINT_TO_POINTER (idx));
+
+       return idx;
+}
+
+
+/*
+ * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
+ * dest may be misaligned.
+ */
+static void
+swap_with_size (char *dest, const char* val, int len, int nelem) {
+       MONO_REQ_GC_NEUTRAL_MODE;
+#if G_BYTE_ORDER != G_LITTLE_ENDIAN
+       int elem;
+
+       for (elem = 0; elem < nelem; ++elem) {
+               switch (len) {
+               case 1:
+                       *dest = *val;
+                       break;
+               case 2:
+                       dest [0] = val [1];
+                       dest [1] = val [0];
+                       break;
+               case 4:
+                       dest [0] = val [3];
+                       dest [1] = val [2];
+                       dest [2] = val [1];
+                       dest [3] = val [0];
+                       break;
+               case 8:
+                       dest [0] = val [7];
+                       dest [1] = val [6];
+                       dest [2] = val [5];
+                       dest [3] = val [4];
+                       dest [4] = val [3];
+                       dest [5] = val [2];
+                       dest [6] = val [1];
+                       dest [7] = val [0];
+                       break;
+               default:
+                       g_assert_not_reached ();
+               }
+               dest += len;
+               val += len;
+       }
+#else
+       memcpy (dest, val, len * nelem);
+#endif
+}
+
+
+guint32
+mono_dynimage_encode_constant (MonoDynamicImage *assembly, MonoObject *val, MonoTypeEnum *ret_type)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       char blob_size [64];
+       char *b = blob_size;
+       char *box_val;
+       char* buf;
+       guint32 idx = 0, len = 0, dummy = 0;
+
+       buf = (char *)g_malloc (64);
+       if (!val) {
+               *ret_type = MONO_TYPE_CLASS;
+               len = 4;
+               box_val = (char*)&dummy;
+       } else {
+               box_val = ((char*)val) + sizeof (MonoObject);
+               *ret_type = val->vtable->klass->byval_arg.type;
+       }
+handle_enum:
+       switch (*ret_type) {
+       case MONO_TYPE_BOOLEAN:
+       case MONO_TYPE_U1:
+       case MONO_TYPE_I1:
+               len = 1;
+               break;
+       case MONO_TYPE_CHAR:
+       case MONO_TYPE_U2:
+       case MONO_TYPE_I2:
+               len = 2;
+               break;
+       case MONO_TYPE_U4:
+       case MONO_TYPE_I4:
+       case MONO_TYPE_R4:
+               len = 4;
+               break;
+       case MONO_TYPE_U8:
+       case MONO_TYPE_I8:
+               len = 8;
+               break;
+       case MONO_TYPE_R8:
+               len = 8;
+               break;
+       case MONO_TYPE_VALUETYPE: {
+               MonoClass *klass = val->vtable->klass;
+               
+               if (klass->enumtype) {
+                       *ret_type = mono_class_enum_basetype (klass)->type;
+                       goto handle_enum;
+               } else if (mono_is_corlib_image (klass->image) && strcmp (klass->name_space, "System") == 0 && strcmp (klass->name, "DateTime") == 0) {
+                       len = 8;
+               } else 
+                       g_error ("we can't encode valuetypes, we should have never reached this line");
+               break;
+       }
+       case MONO_TYPE_CLASS:
+               break;
+       case MONO_TYPE_STRING: {
+               MonoString *str = (MonoString*)val;
+               /* there is no signature */
+               len = str->length * 2;
+               mono_metadata_encode_value (len, b, &b);
+#if G_BYTE_ORDER != G_LITTLE_ENDIAN
+               {
+                       char *swapped = g_malloc (2 * mono_string_length (str));
+                       const char *p = (const char*)mono_string_chars (str);
+
+                       swap_with_size (swapped, p, 2, mono_string_length (str));
+                       idx = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, swapped, len);
+                       g_free (swapped);
+               }
+#else
+               idx = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, (char*)mono_string_chars (str), len);
+#endif
+
+               g_free (buf);
+               return idx;
+       }
+       case MONO_TYPE_GENERICINST:
+               *ret_type = val->vtable->klass->generic_class->container_class->byval_arg.type;
+               goto handle_enum;
+       default:
+               g_error ("we don't encode constant type 0x%02x yet", *ret_type);
+       }
+
+       /* there is no signature */
+       mono_metadata_encode_value (len, b, &b);
+#if G_BYTE_ORDER != G_LITTLE_ENDIAN
+       idx = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
+       swap_with_size (blob_size, box_val, len, 1);
+       mono_image_add_stream_data (&assembly->blob, blob_size, len);
+#else
+       idx = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, box_val, len);
+#endif
+
+       g_free (buf);
+       return idx;
+}
+
+
+guint32
+mono_dynimage_encode_field_signature (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       mono_error_init (error);
+
+       SigBuffer buf;
+       guint32 idx;
+       guint32 typespec = 0;
+       MonoType *type;
+       MonoClass *klass;
+
+       mono_reflection_init_type_builder_generics (fb->type, error);
+       return_val_if_nok (error, 0);
+
+       type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
+       return_val_if_nok (error, 0);
+       klass = mono_class_from_mono_type (type);
+
+       sigbuffer_init (&buf, 32);
+       
+       sigbuffer_add_value (&buf, 0x06);
+       encode_custom_modifiers (assembly, fb->modreq, fb->modopt, &buf, error);
+       if (!is_ok (error))
+               goto fail;
+       /* encode custom attributes before the type */
+
+       if (klass->generic_container)
+               typespec = create_typespec (assembly, type);
+
+       if (typespec) {
+               MonoGenericClass *gclass;
+               gclass = mono_metadata_lookup_generic_class (klass, klass->generic_container->context.class_inst, TRUE);
+               encode_generic_class (assembly, gclass, &buf);
+       } else {
+               encode_type (assembly, type, &buf);
+       }
+       idx = sigbuffer_add_to_blob_cached (assembly, &buf);
+       sigbuffer_free (&buf);
+       return idx;
+fail:
+       sigbuffer_free (&buf);
+       return 0;
+}
+
+#ifndef DISABLE_REFLECTION_EMIT
+/*field_image is the image to which the eventual custom mods have been encoded against*/
+guint32
+mono_dynimage_encode_fieldref_signature (MonoDynamicImage *assembly, MonoImage *field_image, MonoType *type)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       SigBuffer buf;
+       guint32 idx, i, token;
+
+       if (!assembly->save)
+               return 0;
+
+       sigbuffer_init (&buf, 32);
+       
+       sigbuffer_add_value (&buf, 0x06);
+       /* encode custom attributes before the type */
+       if (type->num_mods) {
+               for (i = 0; i < type->num_mods; ++i) {
+                       if (field_image) {
+                               MonoError error;
+                               MonoClass *klass = mono_class_get_checked (field_image, type->modifiers [i].token, &error);
+                               g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
+
+                               token = mono_image_typedef_or_ref (assembly, &klass->byval_arg);
+                       } else {
+                               token = type->modifiers [i].token;
+                       }
+
+                       if (type->modifiers [i].required)
+                               sigbuffer_add_byte (&buf, MONO_TYPE_CMOD_REQD);
+                       else
+                               sigbuffer_add_byte (&buf, MONO_TYPE_CMOD_OPT);
+
+                       sigbuffer_add_value (&buf, token);
+               }
+       }
+       encode_type (assembly, type, &buf);
+       idx = sigbuffer_add_to_blob_cached (assembly, &buf);
+       sigbuffer_free (&buf);
+       return idx;
+}
+#else /* DISABLE_REFLECTION_EMIT */
+guint32
+mono_dynimage_encode_fieldref_signature (MonoDynamicImage *assembly, MonoImage *field_image, MonoType *type)
+{
+       g_assert_not_reached ();
+       return 0;
+}
+#endif /* DISABLE_REFLECTION_EMIT */
+
+static guint32
+create_typespec (MonoDynamicImage *assembly, MonoType *type)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       MonoDynamicTable *table;
+       guint32 *values;
+       guint32 token;
+       SigBuffer buf;
+
+       if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typespec, type))))
+               return token;
+
+       sigbuffer_init (&buf, 32);
+       switch (type->type) {
+       case MONO_TYPE_FNPTR:
+       case MONO_TYPE_PTR:
+       case MONO_TYPE_SZARRAY:
+       case MONO_TYPE_ARRAY:
+       case MONO_TYPE_VAR:
+       case MONO_TYPE_MVAR:
+       case MONO_TYPE_GENERICINST:
+               encode_type (assembly, type, &buf);
+               break;
+       case MONO_TYPE_CLASS:
+       case MONO_TYPE_VALUETYPE: {
+               MonoClass *k = mono_class_from_mono_type (type);
+               if (!k || !k->generic_container) {
+                       sigbuffer_free (&buf);
+                       return 0;
+               }
+               encode_type (assembly, type, &buf);
+               break;
+       }
+       default:
+               sigbuffer_free (&buf);
+               return 0;
+       }
+
+       table = &assembly->tables [MONO_TABLE_TYPESPEC];
+       if (assembly->save) {
+               token = sigbuffer_add_to_blob_cached (assembly, &buf);
+               alloc_table (table, table->rows + 1);
+               values = table->values + table->next_idx * MONO_TYPESPEC_SIZE;
+               values [MONO_TYPESPEC_SIGNATURE] = token;
+       }
+       sigbuffer_free (&buf);
+
+       token = MONO_TYPEDEFORREF_TYPESPEC | (table->next_idx << MONO_TYPEDEFORREF_BITS);
+       g_hash_table_insert (assembly->typespec, type, GUINT_TO_POINTER(token));
+       table->next_idx ++;
+       return token;
+}
+
+guint32
+mono_dynimage_encode_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType *type, gboolean try_typespec)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       MonoDynamicTable *table;
+       guint32 *values;
+       guint32 token, scope, enclosing;
+       MonoClass *klass;
+
+       /* if the type requires a typespec, we must try that first*/
+       if (try_typespec && (token = create_typespec (assembly, type)))
+               return token;
+       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typeref, type));
+       if (token)
+               return token;
+       klass = mono_class_from_mono_type (type);
+       if (!klass)
+               klass = mono_class_from_mono_type (type);
+
+       /*
+        * If it's in the same module and not a generic type parameter:
+        */
+       if ((klass->image == &assembly->image) && (type->type != MONO_TYPE_VAR) && 
+                       (type->type != MONO_TYPE_MVAR)) {
+               MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
+               token = MONO_TYPEDEFORREF_TYPEDEF | (tb->table_idx << MONO_TYPEDEFORREF_BITS);
+               mono_dynamic_image_register_token (assembly, token, (MonoObject *)mono_class_get_ref_info (klass));
+               return token;
+       }
+
+       if (klass->nested_in) {
+               enclosing = mono_dynimage_encode_typedef_or_ref_full (assembly, &klass->nested_in->byval_arg, FALSE);
+               /* get the typeref idx of the enclosing type */
+               enclosing >>= MONO_TYPEDEFORREF_BITS;
+               scope = (enclosing << MONO_RESOLUTION_SCOPE_BITS) | MONO_RESOLUTION_SCOPE_TYPEREF;
+       } else {
+               scope = mono_reflection_resolution_scope_from_image (assembly, klass->image);
+       }
+       table = &assembly->tables [MONO_TABLE_TYPEREF];
+       if (assembly->save) {
+               alloc_table (table, table->rows + 1);
+               values = table->values + table->next_idx * MONO_TYPEREF_SIZE;
+               values [MONO_TYPEREF_SCOPE] = scope;
+               values [MONO_TYPEREF_NAME] = mono_dynstream_insert_string (&assembly->sheap, klass->name);
+               values [MONO_TYPEREF_NAMESPACE] = mono_dynstream_insert_string (&assembly->sheap, klass->name_space);
+       }
+       token = MONO_TYPEDEFORREF_TYPEREF | (table->next_idx << MONO_TYPEDEFORREF_BITS); /* typeref */
+       g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token));
+       table->next_idx ++;
+       mono_dynamic_image_register_token (assembly, token, (MonoObject *)mono_class_get_ref_info (klass));
+       return token;
+}
+
+/*
+ * Despite the name, we handle also TypeSpec (with the above helper).
+ */
+static guint32
+mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
+{
+       return mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
+}
+
+guint32
+mono_dynimage_encode_generic_method_definition_sig (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb)
+{
+       SigBuffer buf;
+       int i;
+       guint32 nparams = mono_array_length (mb->generic_params);
+       guint32 idx;
+
+       if (!assembly->save)
+               return 0;
+
+       sigbuffer_init (&buf, 32);
+
+       sigbuffer_add_value (&buf, 0xa);
+       sigbuffer_add_value (&buf, nparams);
+
+       for (i = 0; i < nparams; i++) {
+               sigbuffer_add_value (&buf, MONO_TYPE_MVAR);
+               sigbuffer_add_value (&buf, i);
+       }
+
+       idx = sigbuffer_add_to_blob_cached (assembly, &buf);
+       sigbuffer_free (&buf);
+       return idx;
+}
+
+guint32
+mono_dynimage_encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericContext *context)
+{
+       SigBuffer buf;
+       int i;
+       guint32 nparams = context->method_inst->type_argc;
+       guint32 idx;
+
+       if (!assembly->save)
+               return 0;
+
+       sigbuffer_init (&buf, 32);
+       /*
+        * FIXME: vararg, explicit_this, differenc call_conv values...
+        */
+       sigbuffer_add_value (&buf, 0xa); /* FIXME FIXME FIXME */
+       sigbuffer_add_value (&buf, nparams);
+
+       for (i = 0; i < nparams; i++)
+               encode_type (assembly, context->method_inst->type_argv [i], &buf);
+
+       idx = sigbuffer_add_to_blob_cached (assembly, &buf);
+       sigbuffer_free (&buf);
+       return idx;
+}
+
+#ifndef DISABLE_REFLECTION_EMIT
+guint32
+mono_dynimage_encode_generic_typespec (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *tb, MonoError *error)
+{
+       MonoDynamicTable *table;
+       MonoClass *klass;
+       MonoType *type;
+       guint32 *values;
+       guint32 token;
+       SigBuffer buf;
+       int count, i;
+
+       /*
+        * We're creating a TypeSpec for the TypeBuilder of a generic type declaration,
+        * ie. what we'd normally use as the generic type in a TypeSpec signature.
+        * Because of this, we must not insert it into the `typeref' hash table.
+        */
+       type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
+       return_val_if_nok (error, 0);
+       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typespec, type));
+       if (token)
+               return token;
+
+       sigbuffer_init (&buf, 32);
+
+       g_assert (tb->generic_params);
+       klass = mono_class_from_mono_type (type);
+
+       if (tb->generic_container) {
+               if (!mono_reflection_create_generic_class (tb, error))
+                       goto fail;
+       }
+
+       sigbuffer_add_value (&buf, MONO_TYPE_GENERICINST);
+       g_assert (klass->generic_container);
+       sigbuffer_add_value (&buf, klass->byval_arg.type);
+       sigbuffer_add_value (&buf, mono_dynimage_encode_typedef_or_ref_full (assembly, &klass->byval_arg, FALSE));
+
+       count = mono_array_length (tb->generic_params);
+       sigbuffer_add_value (&buf, count);
+       for (i = 0; i < count; i++) {
+               MonoReflectionGenericParam *gparam;
+
+               gparam = mono_array_get (tb->generic_params, MonoReflectionGenericParam *, i);
+               MonoType *gparam_type = mono_reflection_type_get_handle ((MonoReflectionType*)gparam, error);
+               if (!is_ok (error))
+                       goto fail;
+
+               encode_type (assembly, gparam_type, &buf);
+       }
+
+       table = &assembly->tables [MONO_TABLE_TYPESPEC];
+
+       if (assembly->save) {
+               token = sigbuffer_add_to_blob_cached (assembly, &buf);
+               alloc_table (table, table->rows + 1);
+               values = table->values + table->next_idx * MONO_TYPESPEC_SIZE;
+               values [MONO_TYPESPEC_SIGNATURE] = token;
+       }
+       sigbuffer_free (&buf);
+
+       token = MONO_TYPEDEFORREF_TYPESPEC | (table->next_idx << MONO_TYPEDEFORREF_BITS);
+       g_hash_table_insert (assembly->typespec, type, GUINT_TO_POINTER(token));
+       table->next_idx ++;
+       return token;
+fail:
+       sigbuffer_free (&buf);
+       return 0;
+}
+#else /*DISABLE_REFLECTION_EMIT*/
+guint32
+mono_dynimage_encode_generic_typespec (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *tb, MonoError *error)
+{
+       g_assert_not_reached ();
+       return 0;
+}
+#endif /*DISABLE_REFLECTION_EMIT*/
+
+#ifndef DISABLE_REFLECTION_EMIT
+guint32
+mono_dynimage_encode_reflection_sighelper (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error)
+{
+       SigBuffer buf;
+       guint32 nargs;
+       guint32 i, idx;
+
+       mono_error_init (error);
+
+       if (!assembly->save)
+               return 0;
+
+       /* FIXME: this means SignatureHelper.SignatureHelpType.HELPER_METHOD */
+       g_assert (helper->type == 2);
+
+       if (helper->arguments)
+               nargs = mono_array_length (helper->arguments);
+       else
+               nargs = 0;
+
+       sigbuffer_init (&buf, 32);
+
+       /* Encode calling convention */
+       /* Change Any to Standard */
+       if ((helper->call_conv & 0x03) == 0x03)
+               helper->call_conv = 0x01;
+       /* explicit_this implies has_this */
+       if (helper->call_conv & 0x40)
+               helper->call_conv &= 0x20;
+
+       if (helper->call_conv == 0) { /* Unmanaged */
+               idx = helper->unmanaged_call_conv - 1;
+       } else {
+               /* Managed */
+               idx = helper->call_conv & 0x60; /* has_this + explicit_this */
+               if (helper->call_conv & 0x02) /* varargs */
+                       idx += 0x05;
+       }
+
+       sigbuffer_add_byte (&buf, idx);
+       sigbuffer_add_value (&buf, nargs);
+       encode_reflection_type (assembly, helper->return_type, &buf, error);
+       if (!is_ok (error))
+               goto fail;
+       for (i = 0; i < nargs; ++i) {
+               MonoArray *modreqs = NULL;
+               MonoArray *modopts = NULL;
+               MonoReflectionType *pt;
+
+               if (helper->modreqs && (i < mono_array_length (helper->modreqs)))
+                       modreqs = mono_array_get (helper->modreqs, MonoArray*, i);
+               if (helper->modopts && (i < mono_array_length (helper->modopts)))
+                       modopts = mono_array_get (helper->modopts, MonoArray*, i);
+
+               encode_custom_modifiers (assembly, modreqs, modopts, &buf, error);
+               if (!is_ok (error))
+                       goto fail;
+               pt = mono_array_get (helper->arguments, MonoReflectionType*, i);
+               encode_reflection_type (assembly, pt, &buf, error);
+               if (!is_ok (error))
+                       goto fail;
+       }
+       idx = sigbuffer_add_to_blob_cached (assembly, &buf);
+       sigbuffer_free (&buf);
+
+       return idx;
+fail:
+       sigbuffer_free (&buf);
+       return 0;
+}
+#else /* DISABLE_REFLECTION_EMIT */
+guint32
+mono_dynimage_encode_reflection_sighelper (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error)
+{
+       g_assert_not_reached ();
+       return 0;
+}
+#endif /* DISABLE_REFLECTION_EMIT */
+
+static MonoArray *
+reflection_sighelper_get_signature_local (MonoReflectionSigHelper *sig, MonoError *error)
+{
+       MonoReflectionModuleBuilder *module = sig->module;
+       MonoDynamicImage *assembly = module != NULL ? module->dynamic_image : NULL;
+       guint32 na = sig->arguments ? mono_array_length (sig->arguments) : 0;
+       guint32 buflen, i;
+       MonoArray *result;
+       SigBuffer buf;
+
+       mono_error_init (error);
+
+       sigbuffer_init (&buf, 32);
+
+       sigbuffer_add_value (&buf, 0x07);
+       sigbuffer_add_value (&buf, na);
+       if (assembly != NULL){
+               for (i = 0; i < na; ++i) {
+                       MonoReflectionType *type = mono_array_get (sig->arguments, MonoReflectionType*, i);
+                       encode_reflection_type (assembly, type, &buf, error);
+                       if (!is_ok (error)) goto fail;
+               }
+       }
+
+       buflen = buf.p - buf.buf;
+       result = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, buflen, error);
+       if (!is_ok (error)) goto fail;
+       memcpy (mono_array_addr (result, char, 0), buf.buf, buflen);
+       sigbuffer_free (&buf);
+       return result;
+fail:
+       sigbuffer_free (&buf);
+       return NULL;
+}
+
+static MonoArray *
+reflection_sighelper_get_signature_field (MonoReflectionSigHelper *sig, MonoError *error)
+{
+       MonoDynamicImage *assembly = sig->module->dynamic_image;
+       guint32 na = sig->arguments ? mono_array_length (sig->arguments) : 0;
+       guint32 buflen, i;
+       MonoArray *result;
+       SigBuffer buf;
+
+       mono_error_init (error);
+
+       sigbuffer_init (&buf, 32);
+
+       sigbuffer_add_value (&buf, 0x06);
+       for (i = 0; i < na; ++i) {
+               MonoReflectionType *type = mono_array_get (sig->arguments, MonoReflectionType*, i);
+               encode_reflection_type (assembly, type, &buf, error);
+               if (!is_ok (error))
+                       goto fail;
+       }
+
+       buflen = buf.p - buf.buf;
+       result = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, buflen, error);
+       if (!is_ok (error)) goto fail;
+       memcpy (mono_array_addr (result, char, 0), buf.buf, buflen);
+       sigbuffer_free (&buf);
+
+       return result;
+fail:
+       sigbuffer_free (&buf);
+       return NULL;
+}
+
+static char*
+type_get_fully_qualified_name (MonoType *type)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
+}
+
+#ifndef DISABLE_REFLECTION_EMIT_SAVE
+guint32
+mono_dynimage_save_encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       mono_error_init (error);
+
+       char *str;
+       SigBuffer buf;
+       guint32 idx, len;
+
+       sigbuffer_init (&buf, 32);
+
+       sigbuffer_add_value (&buf, minfo->type);
+
+       switch (minfo->type) {
+       case MONO_NATIVE_BYVALTSTR:
+       case MONO_NATIVE_BYVALARRAY:
+               sigbuffer_add_value (&buf, minfo->count);
+               break;
+       case MONO_NATIVE_LPARRAY:
+               if (minfo->eltype || minfo->has_size) {
+                       sigbuffer_add_value (&buf, minfo->eltype);
+                       if (minfo->has_size) {
+                               sigbuffer_add_value (&buf, minfo->param_num != -1? minfo->param_num: 0);
+                               sigbuffer_add_value (&buf, minfo->count != -1? minfo->count: 0);
+
+                               /* LAMESPEC: ElemMult is undocumented */
+                               sigbuffer_add_value (&buf, minfo->param_num != -1? 1: 0);
+                       }
+               }
+               break;
+       case MONO_NATIVE_SAFEARRAY:
+               if (minfo->eltype)
+                       sigbuffer_add_value (&buf, minfo->eltype);
+               break;
+       case MONO_NATIVE_CUSTOM:
+               if (minfo->guid) {
+                       str = mono_string_to_utf8_checked (minfo->guid, error);
+                       if (!is_ok (error)) {
+                               sigbuffer_free (&buf);
+                               return 0;
+                       }
+                       len = strlen (str);
+                       sigbuffer_add_value (&buf, len);
+                       sigbuffer_add_mem (&buf, str, len);
+                       g_free (str);
+               } else {
+                       sigbuffer_add_value (&buf, 0);
+               }
+               /* native type name */
+               sigbuffer_add_value (&buf, 0);
+               /* custom marshaler type name */
+               if (minfo->marshaltype || minfo->marshaltyperef) {
+                       if (minfo->marshaltyperef) {
+                               MonoType *marshaltype = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
+                               if (!is_ok (error)) {
+                                       sigbuffer_free (&buf);
+                                       return 0;
+                               }
+                               str = type_get_fully_qualified_name (marshaltype);
+                       } else {
+                               str = mono_string_to_utf8_checked (minfo->marshaltype, error);
+                               if (!is_ok (error)) {
+                                       sigbuffer_free (&buf);
+                                       return 0;
+                               }
+                       }
+                       len = strlen (str);
+                       sigbuffer_add_value (&buf, len);
+                       sigbuffer_add_mem (&buf, str, len);
+                       g_free (str);
+               } else {
+                       /* FIXME: Actually a bug, since this field is required.  Punting for now ... */
+                       sigbuffer_add_value (&buf, 0);
+               }
+               if (minfo->mcookie) {
+                       str = mono_string_to_utf8_checked (minfo->mcookie, error);
+                       if (!is_ok (error)) {
+                               sigbuffer_free (&buf);
+                               return 0;
+                       }
+                       len = strlen (str);
+                       sigbuffer_add_value (&buf, len);
+                       sigbuffer_add_mem (&buf, str, len);
+                       g_free (str);
+               } else {
+                       sigbuffer_add_value (&buf, 0);
+               }
+               break;
+       default:
+               break;
+       }
+       idx = sigbuffer_add_to_blob_cached (assembly, &buf);
+       sigbuffer_free (&buf);
+       return idx;
+}
+
+guint32
+mono_dynimage_save_encode_property_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBuilder *fb, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       mono_error_init (error);
+
+       SigBuffer buf;
+       guint32 nparams = 0;
+       MonoReflectionMethodBuilder *mb = fb->get_method;
+       MonoReflectionMethodBuilder *smb = fb->set_method;
+       guint32 idx, i;
+
+       if (mb && mb->parameters)
+               nparams = mono_array_length (mb->parameters);
+       if (!mb && smb && smb->parameters)
+               nparams = mono_array_length (smb->parameters) - 1;
+       sigbuffer_init (&buf, 32);
+       if (fb->call_conv & 0x20)
+               sigbuffer_add_byte (&buf, 0x28);
+       else
+               sigbuffer_add_byte (&buf, 0x08);
+       sigbuffer_add_value (&buf, nparams);
+       if (mb) {
+               encode_reflection_type (assembly, (MonoReflectionType*)mb->rtype, &buf, error);
+               if (!is_ok (error))
+                       goto fail;
+               for (i = 0; i < nparams; ++i) {
+                       MonoReflectionType *pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
+                       encode_reflection_type (assembly, pt, &buf, error);
+                       if (!is_ok (error))
+                               goto fail;
+               }
+       } else if (smb && smb->parameters) {
+               /* the property type is the last param */
+               encode_reflection_type (assembly, mono_array_get (smb->parameters, MonoReflectionType*, nparams), &buf, error);
+               if (!is_ok (error))
+                       goto fail;
+
+               for (i = 0; i < nparams; ++i) {
+                       MonoReflectionType *pt = mono_array_get (smb->parameters, MonoReflectionType*, i);
+                       encode_reflection_type (assembly, pt, &buf, error);
+                       if (!is_ok (error))
+                               goto fail;
+               }
+       } else {
+               encode_reflection_type (assembly, (MonoReflectionType*)fb->type, &buf, error);
+               if (!is_ok (error))
+                       goto fail;
+       }
+
+       idx = sigbuffer_add_to_blob_cached (assembly, &buf);
+       sigbuffer_free (&buf);
+       return idx;
+fail:
+       sigbuffer_free (&buf);
+       return 0;
+}
+
+
+#else /*DISABLE_REFLECTION_EMIT_SAVE*/
+guint32
+mono_dynimage_save_encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo, MonoError *error)
+{
+       g_assert_not_reached ();
+       return 0;
+}
+
+guint32
+mono_dynimage_save_encode_property_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBuilder *fb, MonoError *error)
+{
+       g_assert_not_reached ();
+       return 0;
+}
+#endif /*DISABLE_REFLECTION_EMIT_SAVE*/
+
+#ifndef DISABLE_REFLECTION_EMIT
+MonoArray *
+ves_icall_SignatureHelper_get_signature_local (MonoReflectionSigHelper *sig)
+{
+       MonoError error;
+       MonoArray *result = reflection_sighelper_get_signature_local (sig, &error);
+       mono_error_set_pending_exception (&error);
+       return result;
+}
+
+MonoArray *
+ves_icall_SignatureHelper_get_signature_field (MonoReflectionSigHelper *sig)
+{
+       MonoError error;
+       MonoArray *result = reflection_sighelper_get_signature_field (sig, &error);
+       mono_error_set_pending_exception (&error);
+       return result;
+}
+#else /* DISABLE_REFLECTION_EMIT */
+MonoArray *
+ves_icall_SignatureHelper_get_signature_local (MonoReflectionSigHelper *sig)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+MonoArray *
+ves_icall_SignatureHelper_get_signature_field (MonoReflectionSigHelper *sig)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+#endif /* DISABLE_REFLECTION_EMIT */
diff --git a/mono/metadata/sre-internals.h b/mono/metadata/sre-internals.h
new file mode 100644 (file)
index 0000000..87d823a
--- /dev/null
@@ -0,0 +1,157 @@
+/* 
+ * Copyright 2016 Microsoft
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#ifndef __MONO_METADATA_SRE_INTERNALS_H__
+#define __MONO_METADATA_SRE_INTERNALS_H__
+
+#include <mono/metadata/object-internals.h>
+
+typedef struct _ArrayMethod ArrayMethod;
+
+typedef struct {
+       guint32 owner;
+       MonoReflectionGenericParam *gparam;
+} GenericParamTableEntry;
+
+typedef struct {
+       MonoReflectionILGen *ilgen;
+       MonoReflectionType *rtype;
+       MonoArray *parameters;
+       MonoArray *generic_params;
+       MonoGenericContainer *generic_container;
+       MonoArray *pinfo;
+       MonoArray *opt_types;
+       guint32 attrs;
+       guint32 iattrs;
+       guint32 call_conv;
+       guint32 *table_idx; /* note: it's a pointer */
+       MonoArray *code;
+       MonoObject *type;
+       MonoString *name;
+       MonoBoolean init_locals;
+       MonoBoolean skip_visibility;
+       MonoArray *return_modreq;
+       MonoArray *return_modopt;
+       MonoArray *param_modreq;
+       MonoArray *param_modopt;
+       MonoArray *permissions;
+       MonoMethod *mhandle;
+       guint32 nrefs;
+       gpointer *refs;
+       /* for PInvoke */
+       int charset, extra_flags, native_cc;
+       MonoString *dll, *dllentry;
+} ReflectionMethodBuilder;
+
+void
+mono_reflection_emit_init (void);
+
+void
+mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb);
+
+gpointer
+mono_image_g_malloc0 (MonoImage *image, guint size);
+
+gboolean
+mono_is_sre_type_builder (MonoClass *klass);
+
+gboolean
+mono_is_sre_generic_instance (MonoClass *klass);
+
+gboolean
+mono_is_sre_method_on_tb_inst (MonoClass *klass);
+
+gboolean
+mono_is_sre_ctor_builder (MonoClass *klass);
+
+gboolean
+mono_is_sre_ctor_on_tb_inst (MonoClass *klass);
+
+gboolean
+mono_is_sr_mono_cmethod (MonoClass *klass);
+
+gboolean
+mono_is_sr_mono_property (MonoClass *klass);
+
+gboolean
+mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error);
+
+MonoMethod*
+mono_reflection_method_builder_to_mono_method (MonoReflectionMethodBuilder *mb, MonoError *error);
+
+MonoMethod*
+mono_reflection_method_on_tb_inst_get_handle (MonoReflectionMethodOnTypeBuilderInst *m, MonoError *error);
+
+gpointer
+mono_reflection_resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context, MonoError *error);
+
+void
+mono_sre_array_method_free (ArrayMethod *am);
+
+void
+mono_sre_generic_param_table_entry_free (GenericParamTableEntry *entry);
+
+gboolean
+mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb,
+                                                  MonoError *error);
+gboolean
+mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb,
+                                                MonoError *error);
+
+void
+mono_reflection_init_type_builder_generics (MonoObject *type, MonoError *error);
+                                                           
+guint32
+mono_reflection_resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image);
+
+guint32 mono_reflection_method_count_clauses (MonoReflectionILGen *ilgen);
+
+
+/* sre-encode */
+
+guint32
+mono_dynimage_encode_field_signature (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb, MonoError *error);
+
+guint32
+mono_dynimage_encode_constant (MonoDynamicImage *assembly, MonoObject *val, MonoTypeEnum *ret_type);
+
+guint32
+mono_dynimage_encode_locals (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, MonoError *error);
+
+guint32
+mono_dynimage_encode_fieldref_signature (MonoDynamicImage *assembly, MonoImage *field_image, MonoType *type);
+
+guint32
+mono_dynimage_encode_method_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig);
+
+guint32
+mono_dynimage_encode_method_builder_signature (MonoDynamicImage *assembly, ReflectionMethodBuilder *mb,
+                                              MonoError *error);
+
+guint32
+mono_dynimage_encode_generic_method_definition_sig (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb);
+
+guint32
+mono_dynimage_encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericContext *context);
+
+guint32
+mono_dynimage_encode_generic_typespec (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *tb, MonoError *error);
+
+guint32
+mono_dynimage_encode_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType *type, gboolean try_typespec);
+
+guint32
+mono_dynimage_encode_reflection_sighelper (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper,
+                                          MonoError *error);
+
+/* sre-encode, without DISABLE_REFLECTION_EMIT_SAVE (o.w. g_assert_not_reached ()) */
+
+guint32
+mono_dynimage_save_encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo, MonoError *error);
+
+guint32
+mono_dynimage_save_encode_property_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBuilder *fb, MonoError *error);
+
+#endif  /* __MONO_METADATA_SRE_INTERNALS_H__ */
+
diff --git a/mono/metadata/sre-save.c b/mono/metadata/sre-save.c
new file mode 100644 (file)
index 0000000..ff2f93a
--- /dev/null
@@ -0,0 +1,3098 @@
+/*
+ * sre-save.c: Routine for saving an image to a file.
+ *   
+ * 
+ * Author:
+ *   Paolo Molaro (lupus@ximian.com)
+ *
+ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
+ * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
+ * Copyright 2011 Rodrigo Kumpera
+ * 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>
+
+#include "mono/metadata/dynamic-image-internals.h"
+#include "mono/metadata/dynamic-stream-internals.h"
+#include "mono/metadata/mono-ptr-array.h"
+#include "mono/metadata/object-internals.h"
+#include "mono/metadata/sre-internals.h"
+#include "mono/metadata/security-manager.h"
+#include "mono/metadata/tabledefs.h"
+#include "mono/metadata/tokentype.h"
+
+#include "mono/utils/checked-build.h"
+#include "mono/utils/mono-digest.h"
+#include "mono/utils/mono-error-internals.h"
+
+#define TEXT_OFFSET 512
+#define CLI_H_SIZE 136
+#define FILE_ALIGN 512
+#define VIRT_ALIGN 8192
+#define START_TEXT_RVA  0x00002000
+
+static void    mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly);
+
+static void
+alloc_table (MonoDynamicTable *table, guint nrows)
+{
+       mono_dynimage_alloc_table (table, nrows);
+}
+
+static guint32
+string_heap_insert (MonoDynamicStream *sh, const char *str)
+{
+       return mono_dynstream_insert_string (sh, str);
+}
+
+static guint32
+string_heap_insert_mstring (MonoDynamicStream *sh, MonoString *str, MonoError *error)
+{
+       return mono_dynstream_insert_mstring (sh, str, error);
+}
+
+static guint32
+mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
+{
+       return mono_dynstream_add_data (stream, data, len);
+}
+
+static guint32
+mono_image_add_stream_zero (MonoDynamicStream *stream, guint32 len)
+{
+       return mono_dynstream_add_zero (stream, len);
+}
+
+static void
+stream_data_align (MonoDynamicStream *stream)
+{
+       mono_dynstream_data_align (stream);
+}
+
+static guint32
+mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
+{
+       return mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
+}
+
+static guint32
+find_index_in_table (MonoDynamicImage *assembly, int table_idx, int col, guint32 token)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       int i;
+       MonoDynamicTable *table;
+       guint32 *values;
+       
+       table = &assembly->tables [table_idx];
+
+       g_assert (col < table->columns);
+
+       values = table->values + table->columns;
+       for (i = 1; i <= table->rows; ++i) {
+               if (values [col] == token)
+                       return i;
+               values += table->columns;
+       }
+       return 0;
+}
+
+/*
+ * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
+ * dest may be misaligned.
+ */
+static void
+swap_with_size (char *dest, const char* val, int len, int nelem) {
+       MONO_REQ_GC_NEUTRAL_MODE;
+#if G_BYTE_ORDER != G_LITTLE_ENDIAN
+       int elem;
+
+       for (elem = 0; elem < nelem; ++elem) {
+               switch (len) {
+               case 1:
+                       *dest = *val;
+                       break;
+               case 2:
+                       dest [0] = val [1];
+                       dest [1] = val [0];
+                       break;
+               case 4:
+                       dest [0] = val [3];
+                       dest [1] = val [2];
+                       dest [2] = val [1];
+                       dest [3] = val [0];
+                       break;
+               case 8:
+                       dest [0] = val [7];
+                       dest [1] = val [6];
+                       dest [2] = val [5];
+                       dest [3] = val [4];
+                       dest [4] = val [3];
+                       dest [5] = val [2];
+                       dest [6] = val [1];
+                       dest [7] = val [0];
+                       break;
+               default:
+                       g_assert_not_reached ();
+               }
+               dest += len;
+               val += len;
+       }
+#else
+       memcpy (dest, val, len * nelem);
+#endif
+}
+
+static guint32
+add_mono_string_to_blob_cached (MonoDynamicImage *assembly, MonoString *str)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+       
+       char blob_size [64];
+       char *b = blob_size;
+       guint32 idx = 0, len;
+
+       len = str->length * 2;
+       mono_metadata_encode_value (len, b, &b);
+#if G_BYTE_ORDER != G_LITTLE_ENDIAN
+       {
+               char *swapped = g_malloc (2 * mono_string_length (str));
+               const char *p = (const char*)mono_string_chars (str);
+
+               swap_with_size (swapped, p, 2, mono_string_length (str));
+               idx = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, swapped, len);
+               g_free (swapped);
+       }
+#else
+       idx = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, (char*)mono_string_chars (str), len);
+#endif
+       return idx;
+}
+
+/*
+ * idx is the table index of the object
+ * type is one of MONO_CUSTOM_ATTR_*
+ */
+static gboolean
+mono_image_add_cattrs (MonoDynamicImage *assembly, guint32 idx, guint32 type, MonoArray *cattrs, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       MonoDynamicTable *table;
+       MonoReflectionCustomAttr *cattr;
+       guint32 *values;
+       guint32 count, i, token;
+       char blob_size [6];
+       char *p = blob_size;
+       
+       mono_error_init (error);
+
+       /* it is legal to pass a NULL cattrs: we avoid to use the if in a lot of places */
+       if (!cattrs)
+               return TRUE;
+       count = mono_array_length (cattrs);
+       table = &assembly->tables [MONO_TABLE_CUSTOMATTRIBUTE];
+       table->rows += count;
+       alloc_table (table, table->rows);
+       values = table->values + table->next_idx * MONO_CUSTOM_ATTR_SIZE;
+       idx <<= MONO_CUSTOM_ATTR_BITS;
+       idx |= type;
+       for (i = 0; i < count; ++i) {
+               cattr = (MonoReflectionCustomAttr*)mono_array_get (cattrs, gpointer, i);
+               values [MONO_CUSTOM_ATTR_PARENT] = idx;
+               token = mono_image_create_token (assembly, (MonoObject*)cattr->ctor, FALSE, FALSE, error);
+               if (!mono_error_ok (error)) goto fail;
+               type = mono_metadata_token_index (token);
+               type <<= MONO_CUSTOM_ATTR_TYPE_BITS;
+               switch (mono_metadata_token_table (token)) {
+               case MONO_TABLE_METHOD:
+                       type |= MONO_CUSTOM_ATTR_TYPE_METHODDEF;
+                       /*
+                        * fixup_cattrs () needs to fix this up. We can't use image->tokens, since it contains the old token for the
+                        * method, not the one returned by mono_image_create_token ().
+                        */
+                       mono_g_hash_table_insert (assembly->remapped_tokens, GUINT_TO_POINTER (token), cattr->ctor);
+                       break;
+               case MONO_TABLE_MEMBERREF:
+                       type |= MONO_CUSTOM_ATTR_TYPE_MEMBERREF;
+                       break;
+               default:
+                       g_warning ("got wrong token in custom attr");
+                       continue;
+               }
+               values [MONO_CUSTOM_ATTR_TYPE] = type;
+               p = blob_size;
+               mono_metadata_encode_value (mono_array_length (cattr->data), p, &p);
+               values [MONO_CUSTOM_ATTR_VALUE] = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, p - blob_size,
+                       mono_array_addr (cattr->data, char, 0), mono_array_length (cattr->data));
+               values += MONO_CUSTOM_ATTR_SIZE;
+               ++table->next_idx;
+       }
+
+       return TRUE;
+
+fail:
+       return FALSE;
+}
+
+static void
+mono_image_add_decl_security (MonoDynamicImage *assembly, guint32 parent_token, MonoArray *permissions)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       MonoDynamicTable *table;
+       guint32 *values;
+       guint32 count, i, idx;
+       MonoReflectionPermissionSet *perm;
+
+       if (!permissions)
+               return;
+
+       count = mono_array_length (permissions);
+       table = &assembly->tables [MONO_TABLE_DECLSECURITY];
+       table->rows += count;
+       alloc_table (table, table->rows);
+
+       for (i = 0; i < mono_array_length (permissions); ++i) {
+               perm = (MonoReflectionPermissionSet*)mono_array_addr (permissions, MonoReflectionPermissionSet, i);
+
+               values = table->values + table->next_idx * MONO_DECL_SECURITY_SIZE;
+
+               idx = mono_metadata_token_index (parent_token);
+               idx <<= MONO_HAS_DECL_SECURITY_BITS;
+               switch (mono_metadata_token_table (parent_token)) {
+               case MONO_TABLE_TYPEDEF:
+                       idx |= MONO_HAS_DECL_SECURITY_TYPEDEF;
+                       break;
+               case MONO_TABLE_METHOD:
+                       idx |= MONO_HAS_DECL_SECURITY_METHODDEF;
+                       break;
+               case MONO_TABLE_ASSEMBLY:
+                       idx |= MONO_HAS_DECL_SECURITY_ASSEMBLY;
+                       break;
+               default:
+                       g_assert_not_reached ();
+               }
+
+               values [MONO_DECL_SECURITY_ACTION] = perm->action;
+               values [MONO_DECL_SECURITY_PARENT] = idx;
+               values [MONO_DECL_SECURITY_PERMISSIONSET] = add_mono_string_to_blob_cached (assembly, perm->pset);
+
+               ++table->next_idx;
+       }
+}
+
+/**
+ * method_encode_code:
+ *
+ * @assembly the assembly
+ * @mb the managed MethodBuilder
+ * @error set on error
+ *
+ * Note that the return value is not sensible if @error is set.
+ */
+static guint32
+method_encode_code (MonoDynamicImage *assembly, ReflectionMethodBuilder *mb, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       char flags = 0;
+       guint32 idx;
+       guint32 code_size;
+       gint32 max_stack, i;
+       gint32 num_locals = 0;
+       gint32 num_exception = 0;
+       gint maybe_small;
+       guint32 fat_flags;
+       char fat_header [12];
+       guint32 int_value;
+       guint16 short_value;
+       guint32 local_sig = 0;
+       guint32 header_size = 12;
+       MonoArray *code;
+
+       mono_error_init (error);
+
+       if ((mb->attrs & (METHOD_ATTRIBUTE_PINVOKE_IMPL | METHOD_ATTRIBUTE_ABSTRACT)) ||
+                       (mb->iattrs & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME)))
+               return 0;
+
+       /*if (mb->name)
+               g_print ("Encode method %s\n", mono_string_to_utf8 (mb->name));*/
+       if (mb->ilgen) {
+               code = mb->ilgen->code;
+               code_size = mb->ilgen->code_len;
+               max_stack = mb->ilgen->max_stack;
+               num_locals = mb->ilgen->locals ? mono_array_length (mb->ilgen->locals) : 0;
+               if (mb->ilgen->ex_handlers)
+                       num_exception = mono_reflection_method_count_clauses (mb->ilgen);
+       } else {
+               code = mb->code;
+               if (code == NULL){
+                       MonoError inner_error;
+                       char *name = mono_string_to_utf8_checked (mb->name, &inner_error);
+                       if (!is_ok (&inner_error)) {
+                               name = g_strdup ("");
+                               mono_error_cleanup (&inner_error);
+                       }
+                       char *str = g_strdup_printf ("Method %s does not have any IL associated", name);
+                       mono_error_set_argument (error, NULL, "a method does not have any IL associated");
+                       g_free (str);
+                       g_free (name);
+                       return 0;
+               }
+
+               code_size = mono_array_length (code);
+               max_stack = 8; /* we probably need to run a verifier on the code... */
+       }
+
+       stream_data_align (&assembly->code);
+
+       /* check for exceptions, maxstack, locals */
+       maybe_small = (max_stack <= 8) && (!num_locals) && (!num_exception);
+       if (maybe_small) {
+               if (code_size < 64 && !(code_size & 1)) {
+                       flags = (code_size << 2) | 0x2;
+               } else if (code_size < 32 && (code_size & 1)) {
+                       flags = (code_size << 2) | 0x6; /* LAMESPEC: see metadata.c */
+               } else {
+                       goto fat_header;
+               }
+               idx = mono_image_add_stream_data (&assembly->code, &flags, 1);
+               /* add to the fixup todo list */
+               if (mb->ilgen && mb->ilgen->num_token_fixups)
+                       mono_g_hash_table_insert (assembly->token_fixups, mb->ilgen, GUINT_TO_POINTER (idx + 1));
+               mono_image_add_stream_data (&assembly->code, mono_array_addr (code, char, 0), code_size);
+               return assembly->text_rva + idx;
+       } 
+fat_header:
+       if (num_locals) {
+               local_sig = MONO_TOKEN_SIGNATURE | mono_dynimage_encode_locals (assembly, mb->ilgen, error);
+               return_val_if_nok (error, 0);
+       }
+       /* 
+        * FIXME: need to set also the header size in fat_flags.
+        * (and more sects and init locals flags)
+        */
+       fat_flags =  0x03;
+       if (num_exception)
+               fat_flags |= METHOD_HEADER_MORE_SECTS;
+       if (mb->init_locals)
+               fat_flags |= METHOD_HEADER_INIT_LOCALS;
+       fat_header [0] = fat_flags;
+       fat_header [1] = (header_size / 4 ) << 4;
+       short_value = GUINT16_TO_LE (max_stack);
+       memcpy (fat_header + 2, &short_value, 2);
+       int_value = GUINT32_TO_LE (code_size);
+       memcpy (fat_header + 4, &int_value, 4);
+       int_value = GUINT32_TO_LE (local_sig);
+       memcpy (fat_header + 8, &int_value, 4);
+       idx = mono_image_add_stream_data (&assembly->code, fat_header, 12);
+       /* add to the fixup todo list */
+       if (mb->ilgen && mb->ilgen->num_token_fixups)
+               mono_g_hash_table_insert (assembly->token_fixups, mb->ilgen, GUINT_TO_POINTER (idx + 12));
+       
+       mono_image_add_stream_data (&assembly->code, mono_array_addr (code, char, 0), code_size);
+       if (num_exception) {
+               unsigned char sheader [4];
+               MonoILExceptionInfo * ex_info;
+               MonoILExceptionBlock * ex_block;
+               int j;
+
+               stream_data_align (&assembly->code);
+               /* always use fat format for now */
+               sheader [0] = METHOD_HEADER_SECTION_FAT_FORMAT | METHOD_HEADER_SECTION_EHTABLE;
+               num_exception *= 6 * sizeof (guint32);
+               num_exception += 4; /* include the size of the header */
+               sheader [1] = num_exception & 0xff;
+               sheader [2] = (num_exception >> 8) & 0xff;
+               sheader [3] = (num_exception >> 16) & 0xff;
+               mono_image_add_stream_data (&assembly->code, (char*)sheader, 4);
+               /* fat header, so we are already aligned */
+               /* reverse order */
+               for (i = mono_array_length (mb->ilgen->ex_handlers) - 1; i >= 0; --i) {
+                       ex_info = (MonoILExceptionInfo *)mono_array_addr (mb->ilgen->ex_handlers, MonoILExceptionInfo, i);
+                       if (ex_info->handlers) {
+                               int finally_start = ex_info->start + ex_info->len;
+                               for (j = 0; j < mono_array_length (ex_info->handlers); ++j) {
+                                       guint32 val;
+                                       ex_block = (MonoILExceptionBlock*)mono_array_addr (ex_info->handlers, MonoILExceptionBlock, j);
+                                       /* the flags */
+                                       val = GUINT32_TO_LE (ex_block->type);
+                                       mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
+                                       /* try offset */
+                                       val = GUINT32_TO_LE (ex_info->start);
+                                       mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
+                                       /* need fault, too, probably */
+                                       if (ex_block->type == MONO_EXCEPTION_CLAUSE_FINALLY)
+                                               val = GUINT32_TO_LE (finally_start - ex_info->start);
+                                       else
+                                               val = GUINT32_TO_LE (ex_info->len);
+                                       mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
+                                       /* handler offset */
+                                       val = GUINT32_TO_LE (ex_block->start);
+                                       mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
+                                       /* handler len */
+                                       val = GUINT32_TO_LE (ex_block->len);
+                                       mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
+                                       finally_start = ex_block->start + ex_block->len;
+                                       if (ex_block->extype) {
+                                               MonoType *extype = mono_reflection_type_get_handle ((MonoReflectionType*)ex_block->extype, error);
+                                               return_val_if_nok (error, 0);
+
+                                               val = mono_metadata_token_from_dor (mono_image_typedef_or_ref (assembly, extype));
+                                       } else {
+                                               if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
+                                                       val = ex_block->filter_offset;
+                                               else
+                                                       val = 0;
+                                       }
+                                       val = GUINT32_TO_LE (val);
+                                       mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
+                                       /*g_print ("out clause %d: from %d len=%d, handler at %d, %d, finally_start=%d, ex_info->start=%d, ex_info->len=%d, ex_block->type=%d, j=%d, i=%d\n", 
+                                                       clause.flags, clause.try_offset, clause.try_len, clause.handler_offset, clause.handler_len, finally_start, ex_info->start, ex_info->len, ex_block->type, j, i);*/
+                               }
+                       } else {
+                               g_error ("No clauses for ex info block %d", i);
+                       }
+               }
+       }
+       return assembly->text_rva + idx;
+}
+
+/*
+ * Fill in the MethodDef and ParamDef tables for a method.
+ * This is used for both normal methods and constructors.
+ */
+static gboolean
+mono_image_basic_method (ReflectionMethodBuilder *mb, MonoDynamicImage *assembly, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       MonoDynamicTable *table;
+       guint32 *values;
+       guint i, count;
+
+       mono_error_init (error);
+
+       /* room in this table is already allocated */
+       table = &assembly->tables [MONO_TABLE_METHOD];
+       *mb->table_idx = table->next_idx ++;
+       g_hash_table_insert (assembly->method_to_table_idx, mb->mhandle, GUINT_TO_POINTER ((*mb->table_idx)));
+       values = table->values + *mb->table_idx * MONO_METHOD_SIZE;
+       values [MONO_METHOD_NAME] = string_heap_insert_mstring (&assembly->sheap, mb->name, error);
+       return_val_if_nok (error, FALSE);
+       values [MONO_METHOD_FLAGS] = mb->attrs;
+       values [MONO_METHOD_IMPLFLAGS] = mb->iattrs;
+       values [MONO_METHOD_SIGNATURE] = mono_dynimage_encode_method_builder_signature (assembly, mb, error);
+       return_val_if_nok (error, FALSE);
+       values [MONO_METHOD_RVA] = method_encode_code (assembly, mb, error);
+       return_val_if_nok (error, FALSE);
+
+       table = &assembly->tables [MONO_TABLE_PARAM];
+       values [MONO_METHOD_PARAMLIST] = table->next_idx;
+
+       mono_image_add_decl_security (assembly, 
+               mono_metadata_make_token (MONO_TABLE_METHOD, *mb->table_idx), mb->permissions);
+
+       if (mb->pinfo) {
+               MonoDynamicTable *mtable;
+               guint32 *mvalues;
+               
+               mtable = &assembly->tables [MONO_TABLE_FIELDMARSHAL];
+               mvalues = mtable->values + mtable->next_idx * MONO_FIELD_MARSHAL_SIZE;
+               
+               count = 0;
+               for (i = 0; i < mono_array_length (mb->pinfo); ++i) {
+                       if (mono_array_get (mb->pinfo, gpointer, i))
+                               count++;
+               }
+               table->rows += count;
+               alloc_table (table, table->rows);
+               values = table->values + table->next_idx * MONO_PARAM_SIZE;
+               for (i = 0; i < mono_array_length (mb->pinfo); ++i) {
+                       MonoReflectionParamBuilder *pb;
+                       if ((pb = mono_array_get (mb->pinfo, MonoReflectionParamBuilder*, i))) {
+                               values [MONO_PARAM_FLAGS] = pb->attrs;
+                               values [MONO_PARAM_SEQUENCE] = i;
+                               if (pb->name != NULL) {
+                                       values [MONO_PARAM_NAME] = string_heap_insert_mstring (&assembly->sheap, pb->name, error);
+                                       return_val_if_nok (error, FALSE);
+                               } else {
+                                       values [MONO_PARAM_NAME] = 0;
+                               }
+                               values += MONO_PARAM_SIZE;
+                               if (pb->marshal_info) {
+                                       mtable->rows++;
+                                       alloc_table (mtable, mtable->rows);
+                                       mvalues = mtable->values + mtable->rows * MONO_FIELD_MARSHAL_SIZE;
+                                       mvalues [MONO_FIELD_MARSHAL_PARENT] = (table->next_idx << MONO_HAS_FIELD_MARSHAL_BITS) | MONO_HAS_FIELD_MARSHAL_PARAMDEF;
+                                       mvalues [MONO_FIELD_MARSHAL_NATIVE_TYPE] = mono_dynimage_save_encode_marshal_blob (assembly, pb->marshal_info, error);
+                                       return_val_if_nok (error, FALSE);
+                               }
+                               pb->table_idx = table->next_idx++;
+                               if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
+                                       guint32 field_type = 0;
+                                       mtable = &assembly->tables [MONO_TABLE_CONSTANT];
+                                       mtable->rows ++;
+                                       alloc_table (mtable, mtable->rows);
+                                       mvalues = mtable->values + mtable->rows * MONO_CONSTANT_SIZE;
+                                       mvalues [MONO_CONSTANT_PARENT] = MONO_HASCONSTANT_PARAM | (pb->table_idx << MONO_HASCONSTANT_BITS);
+                                       mvalues [MONO_CONSTANT_VALUE] = mono_dynimage_encode_constant (assembly, pb->def_value, &field_type);
+                                       mvalues [MONO_CONSTANT_TYPE] = field_type;
+                                       mvalues [MONO_CONSTANT_PADDING] = 0;
+                               }
+                       }
+               }
+       }
+
+       return TRUE;
+}
+
+static gboolean
+mono_image_add_methodimpl (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mb->type;
+       MonoDynamicTable *table;
+       guint32 *values;
+       guint32 tok;
+       MonoReflectionMethod *m;
+       int i;
+
+       mono_error_init (error);
+
+       if (!mb->override_methods)
+               return TRUE;
+
+       for (i = 0; i < mono_array_length (mb->override_methods); ++i) {
+               m = mono_array_get (mb->override_methods, MonoReflectionMethod*, i);
+
+               table = &assembly->tables [MONO_TABLE_METHODIMPL];
+               table->rows ++;
+               alloc_table (table, table->rows);
+               values = table->values + table->rows * MONO_METHODIMPL_SIZE;
+               values [MONO_METHODIMPL_CLASS] = tb->table_idx;
+               values [MONO_METHODIMPL_BODY] = MONO_METHODDEFORREF_METHODDEF | (mb->table_idx << MONO_METHODDEFORREF_BITS);
+
+               tok = mono_image_create_token (assembly, (MonoObject*)m, FALSE, FALSE, error);
+               return_val_if_nok (error, FALSE);
+
+               switch (mono_metadata_token_table (tok)) {
+               case MONO_TABLE_MEMBERREF:
+                       tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODREF;
+                       break;
+               case MONO_TABLE_METHOD:
+                       tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODDEF;
+                       break;
+               default:
+                       g_assert_not_reached ();
+               }
+               values [MONO_METHODIMPL_DECLARATION] = tok;
+       }
+
+       return TRUE;
+}
+
+#ifndef DISABLE_REFLECTION_EMIT
+static gboolean
+mono_image_get_method_info (MonoReflectionMethodBuilder *mb, MonoDynamicImage *assembly, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       MonoDynamicTable *table;
+       guint32 *values;
+       ReflectionMethodBuilder rmb;
+       int i;
+
+       mono_error_init (error);
+
+       if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error) ||
+           !mono_image_basic_method (&rmb, assembly, error))
+               return FALSE;
+
+       mb->table_idx = *rmb.table_idx;
+
+       if (mb->dll) { /* It's a P/Invoke method */
+               guint32 moduleref;
+               /* map CharSet values to on-disk values */
+               int ncharset = (mb->charset ? (mb->charset - 1) * 2 : 0);
+               int extra_flags = mb->extra_flags;
+               table = &assembly->tables [MONO_TABLE_IMPLMAP];
+               table->rows ++;
+               alloc_table (table, table->rows);
+               values = table->values + table->rows * MONO_IMPLMAP_SIZE;
+               
+               values [MONO_IMPLMAP_FLAGS] = (mb->native_cc << 8) | ncharset | extra_flags;
+               values [MONO_IMPLMAP_MEMBER] = (mb->table_idx << 1) | 1; /* memberforwarded: method */
+               if (mb->dllentry) {
+                       values [MONO_IMPLMAP_NAME] = string_heap_insert_mstring (&assembly->sheap, mb->dllentry, error);
+                       return_val_if_nok (error, FALSE);
+               } else {
+                       values [MONO_IMPLMAP_NAME] = string_heap_insert_mstring (&assembly->sheap, mb->name, error);
+                       return_val_if_nok (error, FALSE);
+               }
+               moduleref = string_heap_insert_mstring (&assembly->sheap, mb->dll, error);
+               return_val_if_nok (error, FALSE);
+               if (!(values [MONO_IMPLMAP_SCOPE] = find_index_in_table (assembly, MONO_TABLE_MODULEREF, MONO_MODULEREF_NAME, moduleref))) {
+                       table = &assembly->tables [MONO_TABLE_MODULEREF];
+                       table->rows ++;
+                       alloc_table (table, table->rows);
+                       table->values [table->rows * MONO_MODULEREF_SIZE + MONO_MODULEREF_NAME] = moduleref;
+                       values [MONO_IMPLMAP_SCOPE] = table->rows;
+               }
+       }
+
+       if (mb->generic_params) {
+               table = &assembly->tables [MONO_TABLE_GENERICPARAM];
+               table->rows += mono_array_length (mb->generic_params);
+               alloc_table (table, table->rows);
+               for (i = 0; i < mono_array_length (mb->generic_params); ++i) {
+                       guint32 owner = MONO_TYPEORMETHOD_METHOD | (mb->table_idx << MONO_TYPEORMETHOD_BITS);
+
+                       mono_image_get_generic_param_info (
+                               (MonoReflectionGenericParam *)mono_array_get (mb->generic_params, gpointer, i), owner, assembly);
+               }
+       }
+
+       return TRUE;
+}
+
+static gboolean
+mono_image_get_ctor_info (MonoDomain *domain, MonoReflectionCtorBuilder *mb, MonoDynamicImage *assembly, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       ReflectionMethodBuilder rmb;
+
+       if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
+               return FALSE;
+
+       if (!mono_image_basic_method (&rmb, assembly, error))
+               return FALSE;
+
+       mb->table_idx = *rmb.table_idx;
+
+       return TRUE;
+}
+#endif
+
+static void
+mono_image_get_field_info (MonoReflectionFieldBuilder *fb, MonoDynamicImage *assembly, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       mono_error_init (error);
+
+       MonoDynamicTable *table;
+       guint32 *values;
+
+       /* maybe this fixup should be done in the C# code */
+       if (fb->attrs & FIELD_ATTRIBUTE_LITERAL)
+               fb->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
+       table = &assembly->tables [MONO_TABLE_FIELD];
+       fb->table_idx = table->next_idx ++;
+       g_hash_table_insert (assembly->field_to_table_idx, fb->handle, GUINT_TO_POINTER (fb->table_idx));
+       values = table->values + fb->table_idx * MONO_FIELD_SIZE;
+       values [MONO_FIELD_NAME] = string_heap_insert_mstring (&assembly->sheap, fb->name, error);
+       return_if_nok (error);
+       values [MONO_FIELD_FLAGS] = fb->attrs;
+       values [MONO_FIELD_SIGNATURE] = mono_dynimage_encode_field_signature (assembly, fb, error);
+       return_if_nok (error);
+
+
+       if (fb->offset != -1) {
+               table = &assembly->tables [MONO_TABLE_FIELDLAYOUT];
+               table->rows ++;
+               alloc_table (table, table->rows);
+               values = table->values + table->rows * MONO_FIELD_LAYOUT_SIZE;
+               values [MONO_FIELD_LAYOUT_FIELD] = fb->table_idx;
+               values [MONO_FIELD_LAYOUT_OFFSET] = fb->offset;
+       }
+       if (fb->attrs & FIELD_ATTRIBUTE_LITERAL) {
+               MonoTypeEnum field_type = (MonoTypeEnum)0;
+               table = &assembly->tables [MONO_TABLE_CONSTANT];
+               table->rows ++;
+               alloc_table (table, table->rows);
+               values = table->values + table->rows * MONO_CONSTANT_SIZE;
+               values [MONO_CONSTANT_PARENT] = MONO_HASCONSTANT_FIEDDEF | (fb->table_idx << MONO_HASCONSTANT_BITS);
+               values [MONO_CONSTANT_VALUE] = mono_dynimage_encode_constant (assembly, fb->def_value, &field_type);
+               values [MONO_CONSTANT_TYPE] = field_type;
+               values [MONO_CONSTANT_PADDING] = 0;
+       }
+       if (fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) {
+               guint32 rva_idx;
+               table = &assembly->tables [MONO_TABLE_FIELDRVA];
+               table->rows ++;
+               alloc_table (table, table->rows);
+               values = table->values + table->rows * MONO_FIELD_RVA_SIZE;
+               values [MONO_FIELD_RVA_FIELD] = fb->table_idx;
+               /*
+                * We store it in the code section because it's simpler for now.
+                */
+               if (fb->rva_data) {
+                       if (mono_array_length (fb->rva_data) >= 10)
+                               stream_data_align (&assembly->code);
+                       rva_idx = mono_image_add_stream_data (&assembly->code, mono_array_addr (fb->rva_data, char, 0), mono_array_length (fb->rva_data));
+               } else
+                       rva_idx = mono_image_add_stream_zero (&assembly->code, mono_class_value_size (fb->handle->parent, NULL));
+               values [MONO_FIELD_RVA_RVA] = rva_idx + assembly->text_rva;
+       }
+       if (fb->marshal_info) {
+               table = &assembly->tables [MONO_TABLE_FIELDMARSHAL];
+               table->rows ++;
+               alloc_table (table, table->rows);
+               values = table->values + table->rows * MONO_FIELD_MARSHAL_SIZE;
+               values [MONO_FIELD_MARSHAL_PARENT] = (fb->table_idx << MONO_HAS_FIELD_MARSHAL_BITS) | MONO_HAS_FIELD_MARSHAL_FIELDSREF;
+               values [MONO_FIELD_MARSHAL_NATIVE_TYPE] = mono_dynimage_save_encode_marshal_blob (assembly, fb->marshal_info, error);
+               return_if_nok (error);
+       }
+}
+
+static void
+mono_image_get_property_info (MonoReflectionPropertyBuilder *pb, MonoDynamicImage *assembly, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       mono_error_init (error);
+
+       MonoDynamicTable *table;
+       guint32 *values;
+       guint num_methods = 0;
+       guint32 semaidx;
+
+       /* 
+        * we need to set things in the following tables:
+        * PROPERTYMAP (info already filled in _get_type_info ())
+        * PROPERTY    (rows already preallocated in _get_type_info ())
+        * METHOD      (method info already done with the generic method code)
+        * METHODSEMANTICS
+        * CONSTANT
+        */
+       table = &assembly->tables [MONO_TABLE_PROPERTY];
+       pb->table_idx = table->next_idx ++;
+       values = table->values + pb->table_idx * MONO_PROPERTY_SIZE;
+       values [MONO_PROPERTY_NAME] = string_heap_insert_mstring (&assembly->sheap, pb->name, error);
+       return_if_nok (error);
+       values [MONO_PROPERTY_FLAGS] = pb->attrs;
+       values [MONO_PROPERTY_TYPE] = mono_dynimage_save_encode_property_signature (assembly, pb, error);
+       return_if_nok (error);
+
+
+       /* FIXME: we still don't handle 'other' methods */
+       if (pb->get_method) num_methods ++;
+       if (pb->set_method) num_methods ++;
+
+       table = &assembly->tables [MONO_TABLE_METHODSEMANTICS];
+       table->rows += num_methods;
+       alloc_table (table, table->rows);
+
+       if (pb->get_method) {
+               semaidx = table->next_idx ++;
+               values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
+               values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_GETTER;
+               values [MONO_METHOD_SEMA_METHOD] = pb->get_method->table_idx;
+               values [MONO_METHOD_SEMA_ASSOCIATION] = (pb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_PROPERTY;
+       }
+       if (pb->set_method) {
+               semaidx = table->next_idx ++;
+               values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
+               values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_SETTER;
+               values [MONO_METHOD_SEMA_METHOD] = pb->set_method->table_idx;
+               values [MONO_METHOD_SEMA_ASSOCIATION] = (pb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_PROPERTY;
+       }
+       if (pb->attrs & PROPERTY_ATTRIBUTE_HAS_DEFAULT) {
+               MonoTypeEnum field_type = (MonoTypeEnum)0;
+               table = &assembly->tables [MONO_TABLE_CONSTANT];
+               table->rows ++;
+               alloc_table (table, table->rows);
+               values = table->values + table->rows * MONO_CONSTANT_SIZE;
+               values [MONO_CONSTANT_PARENT] = MONO_HASCONSTANT_PROPERTY | (pb->table_idx << MONO_HASCONSTANT_BITS);
+               values [MONO_CONSTANT_VALUE] = mono_dynimage_encode_constant (assembly, pb->def_value, &field_type);
+               values [MONO_CONSTANT_TYPE] = field_type;
+               values [MONO_CONSTANT_PADDING] = 0;
+       }
+}
+
+static void
+mono_image_get_event_info (MonoReflectionEventBuilder *eb, MonoDynamicImage *assembly, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       MonoDynamicTable *table;
+       guint32 *values;
+       guint num_methods = 0;
+       guint32 semaidx;
+
+       /* 
+        * we need to set things in the following tables:
+        * EVENTMAP (info already filled in _get_type_info ())
+        * EVENT    (rows already preallocated in _get_type_info ())
+        * METHOD      (method info already done with the generic method code)
+        * METHODSEMANTICS
+        */
+       table = &assembly->tables [MONO_TABLE_EVENT];
+       eb->table_idx = table->next_idx ++;
+       values = table->values + eb->table_idx * MONO_EVENT_SIZE;
+       values [MONO_EVENT_NAME] = string_heap_insert_mstring (&assembly->sheap, eb->name, error);
+       return_if_nok (error);
+       values [MONO_EVENT_FLAGS] = eb->attrs;
+       MonoType *ebtype = mono_reflection_type_get_handle (eb->type, error);
+       return_if_nok (error);
+       values [MONO_EVENT_TYPE] = mono_image_typedef_or_ref (assembly, ebtype);
+
+       /*
+        * FIXME: we still don't handle 'other' methods 
+        */
+       if (eb->add_method) num_methods ++;
+       if (eb->remove_method) num_methods ++;
+       if (eb->raise_method) num_methods ++;
+
+       table = &assembly->tables [MONO_TABLE_METHODSEMANTICS];
+       table->rows += num_methods;
+       alloc_table (table, table->rows);
+
+       if (eb->add_method) {
+               semaidx = table->next_idx ++;
+               values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
+               values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_ADD_ON;
+               values [MONO_METHOD_SEMA_METHOD] = eb->add_method->table_idx;
+               values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_EVENT;
+       }
+       if (eb->remove_method) {
+               semaidx = table->next_idx ++;
+               values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
+               values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_REMOVE_ON;
+               values [MONO_METHOD_SEMA_METHOD] = eb->remove_method->table_idx;
+               values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_EVENT;
+       }
+       if (eb->raise_method) {
+               semaidx = table->next_idx ++;
+               values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
+               values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_FIRE;
+               values [MONO_METHOD_SEMA_METHOD] = eb->raise_method->table_idx;
+               values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_EVENT;
+       }
+}
+
+static void
+encode_constraints (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       mono_error_init (error);
+
+       MonoDynamicTable *table;
+       guint32 num_constraints, i;
+       guint32 *values;
+       guint32 table_idx;
+
+       table = &assembly->tables [MONO_TABLE_GENERICPARAMCONSTRAINT];
+       num_constraints = gparam->iface_constraints ?
+               mono_array_length (gparam->iface_constraints) : 0;
+       table->rows += num_constraints;
+       if (gparam->base_type)
+               table->rows++;
+       alloc_table (table, table->rows);
+
+       if (gparam->base_type) {
+               table_idx = table->next_idx ++;
+               values = table->values + table_idx * MONO_GENPARCONSTRAINT_SIZE;
+
+               MonoType *gpbasetype = mono_reflection_type_get_handle (gparam->base_type, error);
+               return_if_nok (error);
+               values [MONO_GENPARCONSTRAINT_GENERICPAR] = owner;
+               values [MONO_GENPARCONSTRAINT_CONSTRAINT] = mono_image_typedef_or_ref (assembly, gpbasetype);
+       }
+
+       for (i = 0; i < num_constraints; i++) {
+               MonoReflectionType *constraint = (MonoReflectionType *)mono_array_get (
+                       gparam->iface_constraints, gpointer, i);
+
+               table_idx = table->next_idx ++;
+               values = table->values + table_idx * MONO_GENPARCONSTRAINT_SIZE;
+
+               MonoType *constraint_type = mono_reflection_type_get_handle (constraint, error);
+               return_if_nok (error);
+
+               values [MONO_GENPARCONSTRAINT_GENERICPAR] = owner;
+               values [MONO_GENPARCONSTRAINT_CONSTRAINT] = mono_image_typedef_or_ref (assembly, constraint_type);
+       }
+}
+
+static void
+mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       GenericParamTableEntry *entry;
+
+       /*
+        * The GenericParam table must be sorted according to the `owner' field.
+        * We need to do this sorting prior to writing the GenericParamConstraint
+        * table, since we have to use the final GenericParam table indices there
+        * and they must also be sorted.
+        */
+
+       entry = g_new0 (GenericParamTableEntry, 1);
+       entry->owner = owner;
+       /* FIXME: track where gen_params should be freed and remove the GC root as well */
+       MONO_GC_REGISTER_ROOT_IF_MOVING (entry->gparam, MONO_ROOT_SOURCE_REFLECTION, "reflection generic parameter");
+       entry->gparam = gparam;
+       
+       g_ptr_array_add (assembly->gen_params, entry);
+}
+
+static gboolean
+write_generic_param_entry (MonoDynamicImage *assembly, GenericParamTableEntry *entry, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       MonoDynamicTable *table;
+       MonoGenericParam *param;
+       guint32 *values;
+       guint32 table_idx;
+
+       mono_error_init (error);
+
+       table = &assembly->tables [MONO_TABLE_GENERICPARAM];
+       table_idx = table->next_idx ++;
+       values = table->values + table_idx * MONO_GENERICPARAM_SIZE;
+
+       MonoType *gparam_type = mono_reflection_type_get_handle ((MonoReflectionType*)entry->gparam, error);
+       return_val_if_nok (error, FALSE);
+
+       param = gparam_type->data.generic_param;
+
+       values [MONO_GENERICPARAM_OWNER] = entry->owner;
+       values [MONO_GENERICPARAM_FLAGS] = entry->gparam->attrs;
+       values [MONO_GENERICPARAM_NUMBER] = mono_generic_param_num (param);
+       values [MONO_GENERICPARAM_NAME] = string_heap_insert (&assembly->sheap, mono_generic_param_info (param)->name);
+
+       if (!mono_image_add_cattrs (assembly, table_idx, MONO_CUSTOM_ATTR_GENERICPAR, entry->gparam->cattrs, error))
+               return FALSE;
+
+       encode_constraints (entry->gparam, table_idx, assembly, error);
+       return_val_if_nok (error, FALSE);
+
+       return TRUE;
+}
+
+static void
+collect_types (MonoPtrArray *types, MonoReflectionTypeBuilder *type)
+{
+       int i;
+
+       mono_ptr_array_append (*types, type);
+
+       if (!type->subtypes)
+               return;
+
+       for (i = 0; i < mono_array_length (type->subtypes); ++i) {
+               MonoReflectionTypeBuilder *subtype = mono_array_get (type->subtypes, MonoReflectionTypeBuilder*, i);
+               collect_types (types, subtype);
+       }
+}
+
+static gint
+compare_types_by_table_idx (MonoReflectionTypeBuilder **type1, MonoReflectionTypeBuilder **type2)
+{
+       if ((*type1)->table_idx < (*type2)->table_idx)
+               return -1;
+       else
+               if ((*type1)->table_idx > (*type2)->table_idx)
+                       return 1;
+       else
+               return 0;
+}
+
+static gboolean
+params_add_cattrs (MonoDynamicImage *assembly, MonoArray *pinfo, MonoError *error) {
+       int i;
+
+       mono_error_init (error);
+       if (!pinfo)
+               return TRUE;
+       for (i = 0; i < mono_array_length (pinfo); ++i) {
+               MonoReflectionParamBuilder *pb;
+               pb = mono_array_get (pinfo, MonoReflectionParamBuilder *, i);
+               if (!pb)
+                       continue;
+               if (!mono_image_add_cattrs (assembly, pb->table_idx, MONO_CUSTOM_ATTR_PARAMDEF, pb->cattrs, error))
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+
+static gboolean
+type_add_cattrs (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *tb, MonoError *error) {
+       int i;
+
+       mono_error_init (error);
+       
+       if (!mono_image_add_cattrs (assembly, tb->table_idx, MONO_CUSTOM_ATTR_TYPEDEF, tb->cattrs, error))
+               return FALSE;
+       if (tb->fields) {
+               for (i = 0; i < tb->num_fields; ++i) {
+                       MonoReflectionFieldBuilder* fb;
+                       fb = mono_array_get (tb->fields, MonoReflectionFieldBuilder*, i);
+                       if (!mono_image_add_cattrs (assembly, fb->table_idx, MONO_CUSTOM_ATTR_FIELDDEF, fb->cattrs, error))
+                               return FALSE;
+               }
+       }
+       if (tb->events) {
+               for (i = 0; i < mono_array_length (tb->events); ++i) {
+                       MonoReflectionEventBuilder* eb;
+                       eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
+                       if (!mono_image_add_cattrs (assembly, eb->table_idx, MONO_CUSTOM_ATTR_EVENT, eb->cattrs, error))
+                               return FALSE;
+               }
+       }
+       if (tb->properties) {
+               for (i = 0; i < mono_array_length (tb->properties); ++i) {
+                       MonoReflectionPropertyBuilder* pb;
+                       pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
+                       if (!mono_image_add_cattrs (assembly, pb->table_idx, MONO_CUSTOM_ATTR_PROPERTY, pb->cattrs, error))
+                               return FALSE;
+               }
+       }
+       if (tb->ctors) {
+               for (i = 0; i < mono_array_length (tb->ctors); ++i) {
+                       MonoReflectionCtorBuilder* cb;
+                       cb = mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i);
+                       if (!mono_image_add_cattrs (assembly, cb->table_idx, MONO_CUSTOM_ATTR_METHODDEF, cb->cattrs, error) ||
+                           !params_add_cattrs (assembly, cb->pinfo, error))
+                               return FALSE;
+               }
+       }
+
+       if (tb->methods) {
+               for (i = 0; i < tb->num_methods; ++i) {
+                       MonoReflectionMethodBuilder* mb;
+                       mb = mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
+                       if (!mono_image_add_cattrs (assembly, mb->table_idx, MONO_CUSTOM_ATTR_METHODDEF, mb->cattrs, error) ||
+                           !params_add_cattrs (assembly, mb->pinfo, error))
+                               return FALSE;
+               }
+       }
+
+       if (tb->subtypes) {
+               for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
+                       if (!type_add_cattrs (assembly, mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i), error))
+                               return FALSE;
+               }
+       }
+
+       return TRUE;
+}
+
+static gboolean
+module_add_cattrs (MonoDynamicImage *assembly, MonoReflectionModuleBuilder *moduleb, MonoError *error)
+{
+       int i;
+       
+       mono_error_init (error);
+
+       if (!mono_image_add_cattrs (assembly, moduleb->table_idx, MONO_CUSTOM_ATTR_MODULE, moduleb->cattrs, error))
+               return FALSE;
+
+       if (moduleb->global_methods) {
+               for (i = 0; i < mono_array_length (moduleb->global_methods); ++i) {
+                       MonoReflectionMethodBuilder* mb = mono_array_get (moduleb->global_methods, MonoReflectionMethodBuilder*, i);
+                       if (!mono_image_add_cattrs (assembly, mb->table_idx, MONO_CUSTOM_ATTR_METHODDEF, mb->cattrs, error) ||
+                           !params_add_cattrs (assembly, mb->pinfo, error))
+                               return FALSE;
+               }
+       }
+
+       if (moduleb->global_fields) {
+               for (i = 0; i < mono_array_length (moduleb->global_fields); ++i) {
+                       MonoReflectionFieldBuilder *fb = mono_array_get (moduleb->global_fields, MonoReflectionFieldBuilder*, i);
+                       if (!mono_image_add_cattrs (assembly, fb->table_idx, MONO_CUSTOM_ATTR_FIELDDEF, fb->cattrs, error))
+                               return FALSE;
+               }
+       }
+       
+       if (moduleb->types) {
+               for (i = 0; i < moduleb->num_types; ++i) {
+                       if (!type_add_cattrs (assembly, mono_array_get (moduleb->types, MonoReflectionTypeBuilder*, i), error))
+                               return FALSE;
+               }
+       }
+
+       return TRUE;
+}
+
+static gboolean
+mono_image_fill_file_table (MonoDomain *domain, MonoReflectionModule *module, MonoDynamicImage *assembly, MonoError *error)
+{
+       MonoDynamicTable *table;
+       guint32 *values;
+       char blob_size [6];
+       guchar hash [20];
+       char *b = blob_size;
+       char *dir, *path;
+
+       mono_error_init (error);
+
+       table = &assembly->tables [MONO_TABLE_FILE];
+       table->rows++;
+       alloc_table (table, table->rows);
+       values = table->values + table->next_idx * MONO_FILE_SIZE;
+       values [MONO_FILE_FLAGS] = FILE_CONTAINS_METADATA;
+       values [MONO_FILE_NAME] = string_heap_insert (&assembly->sheap, module->image->module_name);
+       if (image_is_dynamic (module->image)) {
+               /* This depends on the fact that the main module is emitted last */
+               dir = mono_string_to_utf8_checked (((MonoReflectionModuleBuilder*)module)->assemblyb->dir, error);
+               return_val_if_nok (error, FALSE);
+               path = g_strdup_printf ("%s%c%s", dir, G_DIR_SEPARATOR, module->image->module_name);
+       } else {
+               dir = NULL;
+               path = g_strdup (module->image->name);
+       }
+       mono_sha1_get_digest_from_file (path, hash);
+       g_free (dir);
+       g_free (path);
+       mono_metadata_encode_value (20, b, &b);
+       values [MONO_FILE_HASH_VALUE] = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
+       mono_image_add_stream_data (&assembly->blob, (char*)hash, 20);
+       table->next_idx ++;
+       return TRUE;
+}
+
+static void
+mono_image_fill_module_table (MonoDomain *domain, MonoReflectionModuleBuilder *mb, MonoDynamicImage *assembly, MonoError *error)
+{
+       MonoDynamicTable *table;
+       int i;
+
+       mono_error_init (error);
+
+       table = &assembly->tables [MONO_TABLE_MODULE];
+       mb->table_idx = table->next_idx ++;
+       table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_NAME] = string_heap_insert_mstring (&assembly->sheap, mb->module.name, error);
+       return_if_nok (error);
+       i = mono_image_add_stream_data (&assembly->guid, mono_array_addr (mb->guid, char, 0), 16);
+       i /= 16;
+       ++i;
+       table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_GENERATION] = 0;
+       table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_MVID] = i;
+       table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_ENC] = 0;
+       table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_ENCBASE] = 0;
+}
+
+static guint32
+mono_image_fill_export_table_from_class (MonoDomain *domain, MonoClass *klass,
+       guint32 module_index, guint32 parent_index, MonoDynamicImage *assembly)
+{
+       MonoDynamicTable *table;
+       guint32 *values;
+       guint32 visib, res;
+
+       visib = klass->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK;
+       if (! ((visib & TYPE_ATTRIBUTE_PUBLIC) || (visib & TYPE_ATTRIBUTE_NESTED_PUBLIC)))
+               return 0;
+
+       table = &assembly->tables [MONO_TABLE_EXPORTEDTYPE];
+       table->rows++;
+       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_TYPEDEF] = klass->type_token;
+       if (klass->nested_in)
+               values [MONO_EXP_TYPE_IMPLEMENTATION] = (parent_index << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_EXP_TYPE;
+       else
+               values [MONO_EXP_TYPE_IMPLEMENTATION] = (module_index << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_FILE;
+       values [MONO_EXP_TYPE_NAME] = string_heap_insert (&assembly->sheap, klass->name);
+       values [MONO_EXP_TYPE_NAMESPACE] = string_heap_insert (&assembly->sheap, klass->name_space);
+
+       res = table->next_idx;
+
+       table->next_idx ++;
+
+       /* Emit nested types */
+       if (klass->ext && klass->ext->nested_classes) {
+               GList *tmp;
+
+               for (tmp = klass->ext->nested_classes; tmp; tmp = tmp->next)
+                       mono_image_fill_export_table_from_class (domain, (MonoClass *)tmp->data, module_index, table->next_idx - 1, assembly);
+       }
+
+       return res;
+}
+
+static void
+mono_image_fill_export_table (MonoDomain *domain, MonoReflectionTypeBuilder *tb,
+                             guint32 module_index, guint32 parent_index, MonoDynamicImage *assembly,
+                             MonoError *error)
+{
+       MonoClass *klass;
+       guint32 idx, i;
+
+       mono_error_init (error);
+
+       MonoType *t = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
+       return_if_nok (error);
+
+       klass = mono_class_from_mono_type (t);
+
+       klass->type_token = mono_metadata_make_token (MONO_TABLE_TYPEDEF, tb->table_idx);
+
+       idx = mono_image_fill_export_table_from_class (domain, klass, module_index, 
+                                                                                                  parent_index, assembly);
+
+       /* 
+        * Emit nested types
+        * We need to do this ourselves since klass->nested_classes is not set up.
+        */
+       if (tb->subtypes) {
+               for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
+                       mono_image_fill_export_table (domain, mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i), module_index, idx, assembly, error);
+                       return_if_nok (error);
+               }
+       }
+}
+
+static void
+mono_image_fill_export_table_from_module (MonoDomain *domain, MonoReflectionModule *module,
+       guint32 module_index, MonoDynamicImage *assembly)
+{
+       MonoImage *image = module->image;
+       MonoTableInfo  *t;
+       guint32 i;
+
+       t = &image->tables [MONO_TABLE_TYPEDEF];
+
+       for (i = 0; i < t->rows; ++i) {
+               MonoError error;
+               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)
+                       mono_image_fill_export_table_from_class (domain, klass, module_index, 0, assembly);
+       }
+}
+
+static void
+add_exported_type (MonoReflectionAssemblyBuilder *assemblyb, MonoDynamicImage *assembly, MonoClass *klass, guint32 parent_index)
+{
+       MonoDynamicTable *table;
+       guint32 *values;
+       guint32 scope, scope_idx, impl, current_idx;
+       gboolean forwarder = TRUE;
+       gpointer iter = NULL;
+       MonoClass *nested;
+
+       if (klass->nested_in) {
+               impl = (parent_index << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_EXP_TYPE;
+               forwarder = FALSE;
+       } else {
+               scope = mono_reflection_resolution_scope_from_image (assembly, klass->image);
+               g_assert ((scope & MONO_RESOLUTION_SCOPE_MASK) == MONO_RESOLUTION_SCOPE_ASSEMBLYREF);
+               scope_idx = scope >> MONO_RESOLUTION_SCOPE_BITS;
+               impl = (scope_idx << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_ASSEMBLYREF;
+       }
+
+       table = &assembly->tables [MONO_TABLE_EXPORTEDTYPE];
+
+       table->rows++;
+       alloc_table (table, table->rows);
+       current_idx = table->next_idx;
+       values = table->values + current_idx * MONO_EXP_TYPE_SIZE;
+
+       values [MONO_EXP_TYPE_FLAGS] = forwarder ? TYPE_ATTRIBUTE_FORWARDER : 0;
+       values [MONO_EXP_TYPE_TYPEDEF] = 0;
+       values [MONO_EXP_TYPE_IMPLEMENTATION] = impl;
+       values [MONO_EXP_TYPE_NAME] = string_heap_insert (&assembly->sheap, klass->name);
+       values [MONO_EXP_TYPE_NAMESPACE] = string_heap_insert (&assembly->sheap, klass->name_space);
+
+       table->next_idx++;
+
+       while ((nested = mono_class_get_nested_types (klass, &iter)))
+               add_exported_type (assemblyb, assembly, nested, current_idx);
+}
+
+static void
+mono_image_fill_export_table_from_type_forwarders (MonoReflectionAssemblyBuilder *assemblyb, MonoDynamicImage *assembly)
+{
+       MonoError error;
+       MonoClass *klass;
+       int i;
+
+       if (!assemblyb->type_forwarders)
+               return;
+
+       for (i = 0; i < mono_array_length (assemblyb->type_forwarders); ++i) {
+               MonoReflectionType *t = mono_array_get (assemblyb->type_forwarders, MonoReflectionType *, i);
+               MonoType *type;
+               if (!t)
+                       continue;
+
+               type = mono_reflection_type_get_handle (t, &error);
+               mono_error_assert_ok (&error);
+               g_assert (type);
+
+               klass = mono_class_from_mono_type (type);
+
+               add_exported_type (assemblyb, assembly, klass, 0);
+       }
+}
+
+#define align_pointer(base,p)\
+       do {\
+               guint32 __diff = (unsigned char*)(p)-(unsigned char*)(base);\
+               if (__diff & 3)\
+                       (p) += 4 - (__diff & 3);\
+       } while (0)
+
+static int
+compare_constants (const void *a, const void *b)
+{
+       const guint32 *a_values = (const guint32 *)a;
+       const guint32 *b_values = (const guint32 *)b;
+       return a_values [MONO_CONSTANT_PARENT] - b_values [MONO_CONSTANT_PARENT];
+}
+
+static int
+compare_semantics (const void *a, const void *b)
+{
+       const guint32 *a_values = (const guint32 *)a;
+       const guint32 *b_values = (const guint32 *)b;
+       int assoc = a_values [MONO_METHOD_SEMA_ASSOCIATION] - b_values [MONO_METHOD_SEMA_ASSOCIATION];
+       if (assoc)
+               return assoc;
+       return a_values [MONO_METHOD_SEMA_SEMANTICS] - b_values [MONO_METHOD_SEMA_SEMANTICS];
+}
+
+static int
+compare_custom_attrs (const void *a, const void *b)
+{
+       const guint32 *a_values = (const guint32 *)a;
+       const guint32 *b_values = (const guint32 *)b;
+
+       return a_values [MONO_CUSTOM_ATTR_PARENT] - b_values [MONO_CUSTOM_ATTR_PARENT];
+}
+
+static int
+compare_field_marshal (const void *a, const void *b)
+{
+       const guint32 *a_values = (const guint32 *)a;
+       const guint32 *b_values = (const guint32 *)b;
+
+       return a_values [MONO_FIELD_MARSHAL_PARENT] - b_values [MONO_FIELD_MARSHAL_PARENT];
+}
+
+static int
+compare_nested (const void *a, const void *b)
+{
+       const guint32 *a_values = (const guint32 *)a;
+       const guint32 *b_values = (const guint32 *)b;
+
+       return a_values [MONO_NESTED_CLASS_NESTED] - b_values [MONO_NESTED_CLASS_NESTED];
+}
+
+static int
+compare_genericparam (const void *a, const void *b)
+{
+       MonoError error;
+       const GenericParamTableEntry **a_entry = (const GenericParamTableEntry **) a;
+       const GenericParamTableEntry **b_entry = (const GenericParamTableEntry **) b;
+
+       if ((*b_entry)->owner == (*a_entry)->owner) {
+               MonoType *a_type = mono_reflection_type_get_handle ((MonoReflectionType*)(*a_entry)->gparam, &error);
+               mono_error_assert_ok (&error);
+               MonoType *b_type = mono_reflection_type_get_handle ((MonoReflectionType*)(*b_entry)->gparam, &error);
+               mono_error_assert_ok (&error);
+               return 
+                       mono_type_get_generic_param_num (a_type) -
+                       mono_type_get_generic_param_num (b_type);
+       } else
+               return (*a_entry)->owner - (*b_entry)->owner;
+}
+
+static int
+compare_declsecurity_attrs (const void *a, const void *b)
+{
+       const guint32 *a_values = (const guint32 *)a;
+       const guint32 *b_values = (const guint32 *)b;
+
+       return a_values [MONO_DECL_SECURITY_PARENT] - b_values [MONO_DECL_SECURITY_PARENT];
+}
+
+static int
+compare_interface_impl (const void *a, const void *b)
+{
+       const guint32 *a_values = (const guint32 *)a;
+       const guint32 *b_values = (const guint32 *)b;
+
+       int klass = a_values [MONO_INTERFACEIMPL_CLASS] - b_values [MONO_INTERFACEIMPL_CLASS];
+       if (klass)
+               return klass;
+
+       return a_values [MONO_INTERFACEIMPL_INTERFACE] - b_values [MONO_INTERFACEIMPL_INTERFACE];
+}
+
+struct StreamDesc {
+       const char *name;
+       MonoDynamicStream *stream;
+};
+
+/*
+ * build_compressed_metadata() fills in the blob of data that represents the 
+ * raw metadata as it will be saved in the PE file. The five streams are output 
+ * and the metadata tables are comnpressed from the guint32 array representation, 
+ * to the compressed on-disk format.
+ */
+static gboolean
+build_compressed_metadata (MonoDynamicImage *assembly, MonoError *error)
+{
+       MonoDynamicTable *table;
+       int i;
+       guint64 valid_mask = 0;
+       guint64 sorted_mask;
+       guint32 heapt_size = 0;
+       guint32 meta_size = 256; /* allow for header and other stuff */
+       guint32 table_offset;
+       guint32 ntables = 0;
+       guint64 *int64val;
+       guint32 *int32val;
+       guint16 *int16val;
+       MonoImage *meta;
+       unsigned char *p;
+       struct StreamDesc stream_desc [5];
+
+       mono_error_init (error);
+
+       qsort (assembly->gen_params->pdata, assembly->gen_params->len, sizeof (gpointer), compare_genericparam);
+       for (i = 0; i < assembly->gen_params->len; i++) {
+               GenericParamTableEntry *entry = (GenericParamTableEntry *)g_ptr_array_index (assembly->gen_params, i);
+               if (!write_generic_param_entry (assembly, entry, error))
+                       return FALSE;
+       }
+
+       stream_desc [0].name  = "#~";
+       stream_desc [0].stream = &assembly->tstream;
+       stream_desc [1].name  = "#Strings";
+       stream_desc [1].stream = &assembly->sheap;
+       stream_desc [2].name  = "#US";
+       stream_desc [2].stream = &assembly->us;
+       stream_desc [3].name  = "#Blob";
+       stream_desc [3].stream = &assembly->blob;
+       stream_desc [4].name  = "#GUID";
+       stream_desc [4].stream = &assembly->guid;
+       
+       /* tables that are sorted */
+       sorted_mask = ((guint64)1 << MONO_TABLE_CONSTANT) | ((guint64)1 << MONO_TABLE_FIELDMARSHAL)
+               | ((guint64)1 << MONO_TABLE_METHODSEMANTICS) | ((guint64)1 << MONO_TABLE_CLASSLAYOUT)
+               | ((guint64)1 << MONO_TABLE_FIELDLAYOUT) | ((guint64)1 << MONO_TABLE_FIELDRVA)
+               | ((guint64)1 << MONO_TABLE_IMPLMAP) | ((guint64)1 << MONO_TABLE_NESTEDCLASS)
+               | ((guint64)1 << MONO_TABLE_METHODIMPL) | ((guint64)1 << MONO_TABLE_CUSTOMATTRIBUTE)
+               | ((guint64)1 << MONO_TABLE_DECLSECURITY) | ((guint64)1 << MONO_TABLE_GENERICPARAM)
+               | ((guint64)1 << MONO_TABLE_INTERFACEIMPL);
+       
+       /* Compute table sizes */
+       /* the MonoImage has already been created in mono_reflection_dynimage_basic_init() */
+       meta = &assembly->image;
+
+       /* sizes should be multiple of 4 */
+       mono_dynstream_data_align (&assembly->blob);
+       mono_dynstream_data_align (&assembly->guid);
+       mono_dynstream_data_align (&assembly->sheap);
+       mono_dynstream_data_align (&assembly->us);
+
+       /* Setup the info used by compute_sizes () */
+       meta->idx_blob_wide = assembly->blob.index >= 65536 ? 1 : 0;
+       meta->idx_guid_wide = assembly->guid.index >= 65536 ? 1 : 0;
+       meta->idx_string_wide = assembly->sheap.index >= 65536 ? 1 : 0;
+
+       meta_size += assembly->blob.index;
+       meta_size += assembly->guid.index;
+       meta_size += assembly->sheap.index;
+       meta_size += assembly->us.index;
+
+       for (i=0; i < MONO_TABLE_NUM; ++i)
+               meta->tables [i].rows = assembly->tables [i].rows;
+       
+       for (i = 0; i < MONO_TABLE_NUM; i++){
+               if (meta->tables [i].rows == 0)
+                       continue;
+               valid_mask |= (guint64)1 << i;
+               ntables ++;
+               meta->tables [i].row_size = mono_metadata_compute_size (
+                       meta, i, &meta->tables [i].size_bitfield);
+               heapt_size += meta->tables [i].row_size * meta->tables [i].rows;
+       }
+       heapt_size += 24; /* #~ header size */
+       heapt_size += ntables * 4;
+       /* make multiple of 4 */
+       heapt_size += 3;
+       heapt_size &= ~3;
+       meta_size += heapt_size;
+       meta->raw_metadata = (char *)g_malloc0 (meta_size);
+       p = (unsigned char*)meta->raw_metadata;
+       /* the metadata signature */
+       *p++ = 'B'; *p++ = 'S'; *p++ = 'J'; *p++ = 'B';
+       /* version numbers and 4 bytes reserved */
+       int16val = (guint16*)p;
+       *int16val++ = GUINT16_TO_LE (meta->md_version_major);
+       *int16val = GUINT16_TO_LE (meta->md_version_minor);
+       p += 8;
+       /* version string */
+       int32val = (guint32*)p;
+       *int32val = GUINT32_TO_LE ((strlen (meta->version) + 3) & (~3)); /* needs to be multiple of 4 */
+       p += 4;
+       memcpy (p, meta->version, strlen (meta->version));
+       p += GUINT32_FROM_LE (*int32val);
+       align_pointer (meta->raw_metadata, p);
+       int16val = (guint16*)p;
+       *int16val++ = GUINT16_TO_LE (0); /* flags must be 0 */
+       *int16val = GUINT16_TO_LE (5); /* number of streams */
+       p += 4;
+
+       /*
+        * write the stream info.
+        */
+       table_offset = (p - (unsigned char*)meta->raw_metadata) + 5 * 8 + 40; /* room needed for stream headers */
+       table_offset += 3; table_offset &= ~3;
+
+       assembly->tstream.index = heapt_size;
+       for (i = 0; i < 5; ++i) {
+               int32val = (guint32*)p;
+               stream_desc [i].stream->offset = table_offset;
+               *int32val++ = GUINT32_TO_LE (table_offset);
+               *int32val = GUINT32_TO_LE (stream_desc [i].stream->index);
+               table_offset += GUINT32_FROM_LE (*int32val);
+               table_offset += 3; table_offset &= ~3;
+               p += 8;
+               strcpy ((char*)p, stream_desc [i].name);
+               p += strlen (stream_desc [i].name) + 1;
+               align_pointer (meta->raw_metadata, p);
+       }
+       /* 
+        * now copy the data, the table stream header and contents goes first.
+        */
+       g_assert ((p - (unsigned char*)meta->raw_metadata) < assembly->tstream.offset);
+       p = (guchar*)meta->raw_metadata + assembly->tstream.offset;
+       int32val = (guint32*)p;
+       *int32val = GUINT32_TO_LE (0); /* reserved */
+       p += 4;
+
+       *p++ = 2; /* version */
+       *p++ = 0;
+
+       if (meta->idx_string_wide)
+               *p |= 0x01;
+       if (meta->idx_guid_wide)
+               *p |= 0x02;
+       if (meta->idx_blob_wide)
+               *p |= 0x04;
+       ++p;
+       *p++ = 1; /* reserved */
+       int64val = (guint64*)p;
+       *int64val++ = GUINT64_TO_LE (valid_mask);
+       *int64val++ = GUINT64_TO_LE (valid_mask & sorted_mask); /* bitvector of sorted tables  */
+       p += 16;
+       int32val = (guint32*)p;
+       for (i = 0; i < MONO_TABLE_NUM; i++){
+               if (meta->tables [i].rows == 0)
+                       continue;
+               *int32val++ = GUINT32_TO_LE (meta->tables [i].rows);
+       }
+       p = (unsigned char*)int32val;
+
+       /* sort the tables that still need sorting */
+       table = &assembly->tables [MONO_TABLE_CONSTANT];
+       if (table->rows)
+               qsort (table->values + MONO_CONSTANT_SIZE, table->rows, sizeof (guint32) * MONO_CONSTANT_SIZE, compare_constants);
+       table = &assembly->tables [MONO_TABLE_METHODSEMANTICS];
+       if (table->rows)
+               qsort (table->values + MONO_METHOD_SEMA_SIZE, table->rows, sizeof (guint32) * MONO_METHOD_SEMA_SIZE, compare_semantics);
+       table = &assembly->tables [MONO_TABLE_CUSTOMATTRIBUTE];
+       if (table->rows)
+               qsort (table->values + MONO_CUSTOM_ATTR_SIZE, table->rows, sizeof (guint32) * MONO_CUSTOM_ATTR_SIZE, compare_custom_attrs);
+       table = &assembly->tables [MONO_TABLE_FIELDMARSHAL];
+       if (table->rows)
+               qsort (table->values + MONO_FIELD_MARSHAL_SIZE, table->rows, sizeof (guint32) * MONO_FIELD_MARSHAL_SIZE, compare_field_marshal);
+       table = &assembly->tables [MONO_TABLE_NESTEDCLASS];
+       if (table->rows)
+               qsort (table->values + MONO_NESTED_CLASS_SIZE, table->rows, sizeof (guint32) * MONO_NESTED_CLASS_SIZE, compare_nested);
+       /* Section 21.11 DeclSecurity in Partition II doesn't specify this to be sorted by MS implementation requires it */
+       table = &assembly->tables [MONO_TABLE_DECLSECURITY];
+       if (table->rows)
+               qsort (table->values + MONO_DECL_SECURITY_SIZE, table->rows, sizeof (guint32) * MONO_DECL_SECURITY_SIZE, compare_declsecurity_attrs);
+       table = &assembly->tables [MONO_TABLE_INTERFACEIMPL];
+       if (table->rows)
+               qsort (table->values + MONO_INTERFACEIMPL_SIZE, table->rows, sizeof (guint32) * MONO_INTERFACEIMPL_SIZE, compare_interface_impl);
+
+       /* compress the tables */
+       for (i = 0; i < MONO_TABLE_NUM; i++){
+               int row, col;
+               guint32 *values;
+               guint32 bitfield = meta->tables [i].size_bitfield;
+               if (!meta->tables [i].rows)
+                       continue;
+               if (assembly->tables [i].columns != mono_metadata_table_count (bitfield))
+                       g_error ("col count mismatch in %d: %d %d", i, assembly->tables [i].columns, mono_metadata_table_count (bitfield));
+               meta->tables [i].base = (char*)p;
+               for (row = 1; row <= meta->tables [i].rows; ++row) {
+                       values = assembly->tables [i].values + row * assembly->tables [i].columns;
+                       for (col = 0; col < assembly->tables [i].columns; ++col) {
+                               switch (mono_metadata_table_size (bitfield, col)) {
+                               case 1:
+                                       *p++ = values [col];
+                                       break;
+                               case 2:
+                                       *p++ = values [col] & 0xff;
+                                       *p++ = (values [col] >> 8) & 0xff;
+                                       break;
+                               case 4:
+                                       *p++ = values [col] & 0xff;
+                                       *p++ = (values [col] >> 8) & 0xff;
+                                       *p++ = (values [col] >> 16) & 0xff;
+                                       *p++ = (values [col] >> 24) & 0xff;
+                                       break;
+                               default:
+                                       g_assert_not_reached ();
+                               }
+                       }
+               }
+               g_assert ((p - (const unsigned char*)meta->tables [i].base) == (meta->tables [i].rows * meta->tables [i].row_size));
+       }
+       
+       g_assert (assembly->guid.offset + assembly->guid.index < meta_size);
+       memcpy (meta->raw_metadata + assembly->sheap.offset, assembly->sheap.data, assembly->sheap.index);
+       memcpy (meta->raw_metadata + assembly->us.offset, assembly->us.data, assembly->us.index);
+       memcpy (meta->raw_metadata + assembly->blob.offset, assembly->blob.data, assembly->blob.index);
+       memcpy (meta->raw_metadata + assembly->guid.offset, assembly->guid.data, assembly->guid.index);
+
+       assembly->meta_size = assembly->guid.offset + assembly->guid.index;
+
+       return TRUE;
+}
+
+/*
+ * Some tables in metadata need to be sorted according to some criteria, but
+ * when methods and fields are first created with reflection, they may be assigned a token
+ * that doesn't correspond to the final token they will get assigned after the sorting.
+ * ILGenerator.cs keeps a fixup table that maps the position of tokens in the IL code stream
+ * with the reflection objects that represent them. Once all the tables are set up, the 
+ * reflection objects will contains the correct table index. fixup_method() will fixup the
+ * tokens for the method with ILGenerator @ilgen.
+ */
+static void
+fixup_method (MonoReflectionILGen *ilgen, gpointer value, MonoDynamicImage *assembly)
+{
+       guint32 code_idx = GPOINTER_TO_UINT (value);
+       MonoReflectionILTokenInfo *iltoken;
+       MonoReflectionFieldBuilder *field;
+       MonoReflectionCtorBuilder *ctor;
+       MonoReflectionMethodBuilder *method;
+       MonoReflectionTypeBuilder *tb;
+       MonoReflectionArrayMethod *am;
+       guint32 i, idx = 0;
+       unsigned char *target;
+
+       for (i = 0; i < ilgen->num_token_fixups; ++i) {
+               iltoken = (MonoReflectionILTokenInfo *)mono_array_addr_with_size (ilgen->token_fixups, sizeof (MonoReflectionILTokenInfo), i);
+               target = (guchar*)assembly->code.data + code_idx + iltoken->code_pos;
+               switch (target [3]) {
+               case MONO_TABLE_FIELD:
+                       if (!strcmp (iltoken->member->vtable->klass->name, "FieldBuilder")) {
+                               field = (MonoReflectionFieldBuilder *)iltoken->member;
+                               idx = field->table_idx;
+                       } else if (!strcmp (iltoken->member->vtable->klass->name, "MonoField")) {
+                               MonoClassField *f = ((MonoReflectionField*)iltoken->member)->field;
+                               idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->field_to_table_idx, f));
+                       } else {
+                               g_assert_not_reached ();
+                       }
+                       break;
+               case MONO_TABLE_METHOD:
+                       if (!strcmp (iltoken->member->vtable->klass->name, "MethodBuilder")) {
+                               method = (MonoReflectionMethodBuilder *)iltoken->member;
+                               idx = method->table_idx;
+                       } else if (!strcmp (iltoken->member->vtable->klass->name, "ConstructorBuilder")) {
+                               ctor = (MonoReflectionCtorBuilder *)iltoken->member;
+                               idx = ctor->table_idx;
+                       } else if (!strcmp (iltoken->member->vtable->klass->name, "MonoMethod") || 
+                                          !strcmp (iltoken->member->vtable->klass->name, "MonoCMethod")) {
+                               MonoMethod *m = ((MonoReflectionMethod*)iltoken->member)->method;
+                               idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->method_to_table_idx, m));
+                       } else {
+                               g_assert_not_reached ();
+                       }
+                       break;
+               case MONO_TABLE_TYPEDEF:
+                       if (strcmp (iltoken->member->vtable->klass->name, "TypeBuilder"))
+                               g_assert_not_reached ();
+                       tb = (MonoReflectionTypeBuilder *)iltoken->member;
+                       idx = tb->table_idx;
+                       break;
+               case MONO_TABLE_MEMBERREF:
+                       if (!strcmp (iltoken->member->vtable->klass->name, "MonoArrayMethod")) {
+                               am = (MonoReflectionArrayMethod*)iltoken->member;
+                               idx = am->table_idx;
+                       } else if (!strcmp (iltoken->member->vtable->klass->name, "MonoMethod") ||
+                                  !strcmp (iltoken->member->vtable->klass->name, "MonoCMethod") ||
+                                  !strcmp (iltoken->member->vtable->klass->name, "MonoGenericMethod") ||
+                                  !strcmp (iltoken->member->vtable->klass->name, "MonoGenericCMethod")) {
+                               MonoMethod *m = ((MonoReflectionMethod*)iltoken->member)->method;
+                               g_assert (m->klass->generic_class || m->klass->generic_container);
+                               continue;
+                       } else if (!strcmp (iltoken->member->vtable->klass->name, "FieldBuilder")) {
+                               continue;
+                       } else if (!strcmp (iltoken->member->vtable->klass->name, "MonoField")) {
+                               continue;
+                       } else if (!strcmp (iltoken->member->vtable->klass->name, "MethodBuilder") ||
+                                       !strcmp (iltoken->member->vtable->klass->name, "ConstructorBuilder")) {
+                               continue;
+                       } else if (!strcmp (iltoken->member->vtable->klass->name, "FieldOnTypeBuilderInst")) {
+                               continue;
+                       } else if (!strcmp (iltoken->member->vtable->klass->name, "MethodOnTypeBuilderInst")) {
+                               continue;
+                       } else if (!strcmp (iltoken->member->vtable->klass->name, "ConstructorOnTypeBuilderInst")) {
+                               continue;
+                       } else {
+                               g_assert_not_reached ();
+                       }
+                       break;
+               case MONO_TABLE_METHODSPEC:
+                       if (!strcmp (iltoken->member->vtable->klass->name, "MonoGenericMethod")) {
+                               MonoMethod *m = ((MonoReflectionMethod*)iltoken->member)->method;
+                               g_assert (mono_method_signature (m)->generic_param_count);
+                               continue;
+                       } else if (!strcmp (iltoken->member->vtable->klass->name, "MethodBuilder")) {
+                               continue;
+                       } else if (!strcmp (iltoken->member->vtable->klass->name, "MethodOnTypeBuilderInst")) {
+                               continue;
+                       } else {
+                               g_assert_not_reached ();
+                       }
+                       break;
+               default:
+                       g_error ("got unexpected table 0x%02x in fixup", target [3]);
+               }
+               target [0] = idx & 0xff;
+               target [1] = (idx >> 8) & 0xff;
+               target [2] = (idx >> 16) & 0xff;
+       }
+}
+
+/*
+ * fixup_cattrs:
+ *
+ *   The CUSTOM_ATTRIBUTE table might contain METHODDEF tokens whose final
+ * value is not known when the table is emitted.
+ */
+static void
+fixup_cattrs (MonoDynamicImage *assembly)
+{
+       MonoDynamicTable *table;
+       guint32 *values;
+       guint32 type, i, idx, token;
+       MonoObject *ctor;
+
+       table = &assembly->tables [MONO_TABLE_CUSTOMATTRIBUTE];
+
+       for (i = 0; i < table->rows; ++i) {
+               values = table->values + ((i + 1) * MONO_CUSTOM_ATTR_SIZE);
+
+               type = values [MONO_CUSTOM_ATTR_TYPE];
+               if ((type & MONO_CUSTOM_ATTR_TYPE_MASK) == MONO_CUSTOM_ATTR_TYPE_METHODDEF) {
+                       idx = type >> MONO_CUSTOM_ATTR_TYPE_BITS;
+                       token = mono_metadata_make_token (MONO_TABLE_METHOD, idx);
+                       ctor = (MonoObject *)mono_g_hash_table_lookup (assembly->remapped_tokens, GUINT_TO_POINTER (token));
+                       g_assert (ctor);
+
+                       if (!strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
+                               MonoMethod *m = ((MonoReflectionMethod*)ctor)->method;
+                               idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->method_to_table_idx, m));
+                               values [MONO_CUSTOM_ATTR_TYPE] = (idx << MONO_CUSTOM_ATTR_TYPE_BITS) | MONO_CUSTOM_ATTR_TYPE_METHODDEF;
+                       } else if (!strcmp (ctor->vtable->klass->name, "ConstructorBuilder")) {
+                               MonoMethod *m = ((MonoReflectionCtorBuilder*)ctor)->mhandle;
+                               idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->method_to_table_idx, m));
+                               values [MONO_CUSTOM_ATTR_TYPE] = (idx << MONO_CUSTOM_ATTR_TYPE_BITS) | MONO_CUSTOM_ATTR_TYPE_METHODDEF;
+                       }
+               }
+       }
+}
+
+static gboolean
+assembly_add_resource_manifest (MonoReflectionModuleBuilder *mb, MonoDynamicImage *assembly, MonoReflectionResource *rsrc, guint32 implementation, MonoError *error)
+{
+       MonoDynamicTable *table;
+       guint32 *values;
+
+       mono_error_init (error);
+
+       table = &assembly->tables [MONO_TABLE_MANIFESTRESOURCE];
+       table->rows++;
+       alloc_table (table, table->rows);
+       values = table->values + table->next_idx * MONO_MANIFEST_SIZE;
+       values [MONO_MANIFEST_OFFSET] = rsrc->offset;
+       values [MONO_MANIFEST_FLAGS] = rsrc->attrs;
+       values [MONO_MANIFEST_NAME] = string_heap_insert_mstring (&assembly->sheap, rsrc->name, error);
+       return_val_if_nok (error, FALSE);
+       values [MONO_MANIFEST_IMPLEMENTATION] = implementation;
+       table->next_idx++;
+       return TRUE;
+}
+
+static gboolean
+assembly_add_resource (MonoReflectionModuleBuilder *mb, MonoDynamicImage *assembly, MonoReflectionResource *rsrc, MonoError *error)
+{
+       MonoDynamicTable *table;
+       guint32 *values;
+       char blob_size [6];
+       guchar hash [20];
+       char *b = blob_size;
+       char *name, *sname;
+       guint32 idx, offset;
+
+       mono_error_init (error);
+
+       if (rsrc->filename) {
+               name = mono_string_to_utf8_checked (rsrc->filename, error);
+               return_val_if_nok (error, FALSE);
+               sname = g_path_get_basename (name);
+       
+               table = &assembly->tables [MONO_TABLE_FILE];
+               table->rows++;
+               alloc_table (table, table->rows);
+               values = table->values + table->next_idx * MONO_FILE_SIZE;
+               values [MONO_FILE_FLAGS] = FILE_CONTAINS_NO_METADATA;
+               values [MONO_FILE_NAME] = string_heap_insert (&assembly->sheap, sname);
+               g_free (sname);
+
+               mono_sha1_get_digest_from_file (name, hash);
+               mono_metadata_encode_value (20, b, &b);
+               values [MONO_FILE_HASH_VALUE] = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
+               mono_image_add_stream_data (&assembly->blob, (char*)hash, 20);
+               g_free (name);
+               idx = table->next_idx++;
+               rsrc->offset = 0;
+               idx = MONO_IMPLEMENTATION_FILE | (idx << MONO_IMPLEMENTATION_BITS);
+       } else {
+               char sizebuf [4];
+               char *data;
+               guint len;
+               if (rsrc->data) {
+                       data = mono_array_addr (rsrc->data, char, 0);
+                       len = mono_array_length (rsrc->data);
+               } else {
+                       data = NULL;
+                       len = 0;
+               }
+               offset = len;
+               sizebuf [0] = offset; sizebuf [1] = offset >> 8;
+               sizebuf [2] = offset >> 16; sizebuf [3] = offset >> 24;
+               rsrc->offset = mono_image_add_stream_data (&assembly->resources, sizebuf, 4);
+               mono_image_add_stream_data (&assembly->resources, data, len);
+
+               if (!mb->is_main)
+                       /* 
+                        * The entry should be emitted into the MANIFESTRESOURCE table of 
+                        * the main module, but that needs to reference the FILE table
+                        * which isn't emitted yet.
+                        */
+                       return TRUE;
+               else
+                       idx = 0;
+       }
+
+       return assembly_add_resource_manifest (mb, assembly, rsrc, idx, error);
+}
+
+static gboolean
+set_version_from_string (MonoString *version, guint32 *values, MonoError *error)
+{
+       gchar *ver, *p, *str;
+       guint32 i;
+       
+       mono_error_init (error);
+
+       values [MONO_ASSEMBLY_MAJOR_VERSION] = 0;
+       values [MONO_ASSEMBLY_MINOR_VERSION] = 0;
+       values [MONO_ASSEMBLY_REV_NUMBER] = 0;
+       values [MONO_ASSEMBLY_BUILD_NUMBER] = 0;
+       if (!version)
+               return TRUE;
+       ver = str = mono_string_to_utf8_checked (version, error);
+       return_val_if_nok (error, FALSE);
+       for (i = 0; i < 4; ++i) {
+               values [MONO_ASSEMBLY_MAJOR_VERSION + i] = strtol (ver, &p, 10);
+               switch (*p) {
+               case '.':
+                       p++;
+                       break;
+               case '*':
+                       /* handle Revision and Build */
+                       p++;
+                       break;
+               }
+               ver = p;
+       }
+       g_free (str);
+       return TRUE;
+}
+
+static guint32
+load_public_key (MonoArray *pkey, MonoDynamicImage *assembly) {
+       gsize len;
+       guint32 token = 0;
+       char blob_size [6];
+       char *b = blob_size;
+
+       if (!pkey)
+               return token;
+
+       len = mono_array_length (pkey);
+       mono_metadata_encode_value (len, b, &b);
+       token = mono_image_add_stream_data (&assembly->blob, blob_size, b - blob_size);
+       mono_image_add_stream_data (&assembly->blob, mono_array_addr (pkey, char, 0), len);
+
+       assembly->public_key = (guint8 *)g_malloc (len);
+       memcpy (assembly->public_key, mono_array_addr (pkey, char, 0), len);
+       assembly->public_key_len = len;
+
+       /* Special case: check for ECMA key (16 bytes) */
+       if ((len == MONO_ECMA_KEY_LENGTH) && mono_is_ecma_key (mono_array_addr (pkey, char, 0), len)) {
+               /* In this case we must reserve 128 bytes (1024 bits) for the signature */
+               assembly->strong_name_size = MONO_DEFAULT_PUBLIC_KEY_LENGTH;
+       } else if (len >= MONO_PUBLIC_KEY_HEADER_LENGTH + MONO_MINIMUM_PUBLIC_KEY_LENGTH) {
+               /* minimum key size (in 2.0) is 384 bits */
+               assembly->strong_name_size = len - MONO_PUBLIC_KEY_HEADER_LENGTH;
+       } else {
+               /* FIXME - verifier */
+               g_warning ("Invalid public key length: %d bits (total: %d)", (int)MONO_PUBLIC_KEY_BIT_SIZE (len), (int)len);
+               assembly->strong_name_size = MONO_DEFAULT_PUBLIC_KEY_LENGTH; /* to be safe */
+       }
+       assembly->strong_name = (char *)g_malloc0 (assembly->strong_name_size);
+
+       return token;
+}
+
+static gboolean
+mono_image_emit_manifest (MonoReflectionModuleBuilder *moduleb, MonoError *error)
+{
+       MonoDynamicTable *table;
+       MonoDynamicImage *assembly;
+       MonoReflectionAssemblyBuilder *assemblyb;
+       MonoDomain *domain;
+       guint32 *values;
+       int i;
+       guint32 module_index;
+
+       mono_error_init (error);
+
+       assemblyb = moduleb->assemblyb;
+       assembly = moduleb->dynamic_image;
+       domain = mono_object_domain (assemblyb);
+
+       /* Emit ASSEMBLY table */
+       table = &assembly->tables [MONO_TABLE_ASSEMBLY];
+       alloc_table (table, 1);
+       values = table->values + MONO_ASSEMBLY_SIZE;
+       values [MONO_ASSEMBLY_HASH_ALG] = assemblyb->algid? assemblyb->algid: ASSEMBLY_HASH_SHA1;
+       values [MONO_ASSEMBLY_NAME] = string_heap_insert_mstring (&assembly->sheap, assemblyb->name, error);
+       return_val_if_nok (error, FALSE);
+       if (assemblyb->culture) {
+               values [MONO_ASSEMBLY_CULTURE] = string_heap_insert_mstring (&assembly->sheap, assemblyb->culture, error);
+               return_val_if_nok (error, FALSE);
+       } else {
+               values [MONO_ASSEMBLY_CULTURE] = string_heap_insert (&assembly->sheap, "");
+       }
+       values [MONO_ASSEMBLY_PUBLIC_KEY] = load_public_key (assemblyb->public_key, assembly);
+       values [MONO_ASSEMBLY_FLAGS] = assemblyb->flags;
+       if (!set_version_from_string (assemblyb->version, values, error))
+               return FALSE;
+
+       /* Emit FILE + EXPORTED_TYPE table */
+       module_index = 0;
+       for (i = 0; i < mono_array_length (assemblyb->modules); ++i) {
+               int j;
+               MonoReflectionModuleBuilder *file_module = 
+                       mono_array_get (assemblyb->modules, MonoReflectionModuleBuilder*, i);
+               if (file_module != moduleb) {
+                       if (!mono_image_fill_file_table (domain, (MonoReflectionModule*)file_module, assembly, error))
+                               return FALSE;
+                       module_index ++;
+                       if (file_module->types) {
+                               for (j = 0; j < file_module->num_types; ++j) {
+                                       MonoReflectionTypeBuilder *tb = mono_array_get (file_module->types, MonoReflectionTypeBuilder*, j);
+                                       mono_image_fill_export_table (domain, tb, module_index, 0, assembly, error);
+                                       return_val_if_nok (error, FALSE);
+                               }
+                       }
+               }
+       }
+       if (assemblyb->loaded_modules) {
+               for (i = 0; i < mono_array_length (assemblyb->loaded_modules); ++i) {
+                       MonoReflectionModule *file_module = 
+                               mono_array_get (assemblyb->loaded_modules, MonoReflectionModule*, i);
+                       if (!mono_image_fill_file_table (domain, file_module, assembly, error))
+                               return FALSE;
+                       module_index ++;
+                       mono_image_fill_export_table_from_module (domain, file_module, module_index, assembly);
+               }
+       }
+       if (assemblyb->type_forwarders)
+               mono_image_fill_export_table_from_type_forwarders (assemblyb, assembly);
+
+       /* Emit MANIFESTRESOURCE table */
+       module_index = 0;
+       for (i = 0; i < mono_array_length (assemblyb->modules); ++i) {
+               int j;
+               MonoReflectionModuleBuilder *file_module = 
+                       mono_array_get (assemblyb->modules, MonoReflectionModuleBuilder*, i);
+               /* The table for the main module is emitted later */
+               if (file_module != moduleb) {
+                       module_index ++;
+                       if (file_module->resources) {
+                               int len = mono_array_length (file_module->resources);
+                               for (j = 0; j < len; ++j) {
+                                       MonoReflectionResource* res = (MonoReflectionResource*)mono_array_addr (file_module->resources, MonoReflectionResource, j);
+                                       if (!assembly_add_resource_manifest (file_module, assembly, res, MONO_IMPLEMENTATION_FILE | (module_index << MONO_IMPLEMENTATION_BITS), error))
+                                               return FALSE;
+                               }
+                       }
+               }
+       }
+       return TRUE;
+}
+
+#ifndef DISABLE_REFLECTION_EMIT_SAVE
+
+/*
+ * Insert into the metadata tables all the info about the TypeBuilder tb.
+ * Data in the tables is inserted in a predefined order, since some tables need to be sorted.
+ */
+static gboolean
+mono_image_get_type_info (MonoDomain *domain, MonoReflectionTypeBuilder *tb, MonoDynamicImage *assembly, MonoError *error)
+{
+       MonoDynamicTable *table;
+       guint *values;
+       int i, is_object = 0, is_system = 0;
+       char *n;
+
+       mono_error_init (error);
+
+       table = &assembly->tables [MONO_TABLE_TYPEDEF];
+       values = table->values + tb->table_idx * MONO_TYPEDEF_SIZE;
+       values [MONO_TYPEDEF_FLAGS] = tb->attrs;
+       n = mono_string_to_utf8_checked (tb->name, error);
+       return_val_if_nok (error, FALSE);
+       if (strcmp (n, "Object") == 0)
+               is_object++;
+       values [MONO_TYPEDEF_NAME] = string_heap_insert (&assembly->sheap, n);
+       g_free (n);
+       n = mono_string_to_utf8_checked (tb->nspace, error);
+       return_val_if_nok (error, FALSE);
+       if (strcmp (n, "System") == 0)
+               is_system++;
+       values [MONO_TYPEDEF_NAMESPACE] = string_heap_insert (&assembly->sheap, n);
+       g_free (n);
+       if (tb->parent && !(is_system && is_object) && 
+                       !(tb->attrs & TYPE_ATTRIBUTE_INTERFACE)) { /* interfaces don't have a parent */
+               MonoType *parent_type = mono_reflection_type_get_handle ((MonoReflectionType*)tb->parent, error);
+               return_val_if_nok (error, FALSE);
+               values [MONO_TYPEDEF_EXTENDS] = mono_image_typedef_or_ref (assembly, parent_type);
+       } else {
+               values [MONO_TYPEDEF_EXTENDS] = 0;
+       }
+       values [MONO_TYPEDEF_FIELD_LIST] = assembly->tables [MONO_TABLE_FIELD].next_idx;
+       values [MONO_TYPEDEF_METHOD_LIST] = assembly->tables [MONO_TABLE_METHOD].next_idx;
+
+       /*
+        * if we have explicitlayout or sequentiallayouts, output data in the
+        * ClassLayout table.
+        */
+       if (((tb->attrs & TYPE_ATTRIBUTE_LAYOUT_MASK) != TYPE_ATTRIBUTE_AUTO_LAYOUT) &&
+                       ((tb->class_size > 0) || (tb->packing_size > 0))) {
+               table = &assembly->tables [MONO_TABLE_CLASSLAYOUT];
+               table->rows++;
+               alloc_table (table, table->rows);
+               values = table->values + table->rows * MONO_CLASS_LAYOUT_SIZE;
+               values [MONO_CLASS_LAYOUT_PARENT] = tb->table_idx;
+               values [MONO_CLASS_LAYOUT_CLASS_SIZE] = tb->class_size;
+               values [MONO_CLASS_LAYOUT_PACKING_SIZE] = tb->packing_size;
+       }
+
+       /* handle interfaces */
+       if (tb->interfaces) {
+               table = &assembly->tables [MONO_TABLE_INTERFACEIMPL];
+               i = table->rows;
+               table->rows += mono_array_length (tb->interfaces);
+               alloc_table (table, table->rows);
+               values = table->values + (i + 1) * MONO_INTERFACEIMPL_SIZE;
+               for (i = 0; i < mono_array_length (tb->interfaces); ++i) {
+                       MonoReflectionType* iface = (MonoReflectionType*) mono_array_get (tb->interfaces, gpointer, i);
+                       MonoType *iface_type = mono_reflection_type_get_handle (iface, error);
+                       return_val_if_nok (error, FALSE);
+                       values [MONO_INTERFACEIMPL_CLASS] = tb->table_idx;
+                       values [MONO_INTERFACEIMPL_INTERFACE] = mono_image_typedef_or_ref (assembly, iface_type);
+                       values += MONO_INTERFACEIMPL_SIZE;
+               }
+       }
+
+       /* handle fields */
+       if (tb->fields) {
+               table = &assembly->tables [MONO_TABLE_FIELD];
+               table->rows += tb->num_fields;
+               alloc_table (table, table->rows);
+               for (i = 0; i < tb->num_fields; ++i) {
+                       mono_image_get_field_info (
+                               mono_array_get (tb->fields, MonoReflectionFieldBuilder*, i), assembly, error);
+                       return_val_if_nok (error, FALSE);
+               }
+       }
+
+       /* handle constructors */
+       if (tb->ctors) {
+               table = &assembly->tables [MONO_TABLE_METHOD];
+               table->rows += mono_array_length (tb->ctors);
+               alloc_table (table, table->rows);
+               for (i = 0; i < mono_array_length (tb->ctors); ++i) {
+                       if (!mono_image_get_ctor_info (domain,
+                                                      mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i),
+                                                      assembly, error))
+                               return FALSE;
+               }
+       }
+
+       /* handle methods */
+       if (tb->methods) {
+               table = &assembly->tables [MONO_TABLE_METHOD];
+               table->rows += tb->num_methods;
+               alloc_table (table, table->rows);
+               for (i = 0; i < tb->num_methods; ++i) {
+                       if (!mono_image_get_method_info (
+                                   mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), assembly, error))
+                               return FALSE;
+               }
+       }
+
+       /* Do the same with properties etc.. */
+       if (tb->events && mono_array_length (tb->events)) {
+               table = &assembly->tables [MONO_TABLE_EVENT];
+               table->rows += mono_array_length (tb->events);
+               alloc_table (table, table->rows);
+               table = &assembly->tables [MONO_TABLE_EVENTMAP];
+               table->rows ++;
+               alloc_table (table, table->rows);
+               values = table->values + table->rows * MONO_EVENT_MAP_SIZE;
+               values [MONO_EVENT_MAP_PARENT] = tb->table_idx;
+               values [MONO_EVENT_MAP_EVENTLIST] = assembly->tables [MONO_TABLE_EVENT].next_idx;
+               for (i = 0; i < mono_array_length (tb->events); ++i) {
+                       mono_image_get_event_info (
+                               mono_array_get (tb->events, MonoReflectionEventBuilder*, i), assembly, error);
+                       return_val_if_nok (error, FALSE);
+               }
+       }
+       if (tb->properties && mono_array_length (tb->properties)) {
+               table = &assembly->tables [MONO_TABLE_PROPERTY];
+               table->rows += mono_array_length (tb->properties);
+               alloc_table (table, table->rows);
+               table = &assembly->tables [MONO_TABLE_PROPERTYMAP];
+               table->rows ++;
+               alloc_table (table, table->rows);
+               values = table->values + table->rows * MONO_PROPERTY_MAP_SIZE;
+               values [MONO_PROPERTY_MAP_PARENT] = tb->table_idx;
+               values [MONO_PROPERTY_MAP_PROPERTY_LIST] = assembly->tables [MONO_TABLE_PROPERTY].next_idx;
+               for (i = 0; i < mono_array_length (tb->properties); ++i) {
+                       mono_image_get_property_info (
+                               mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i), assembly, error);
+                       return_val_if_nok (error, FALSE);
+               }
+       }
+
+       /* handle generic parameters */
+       if (tb->generic_params) {
+               table = &assembly->tables [MONO_TABLE_GENERICPARAM];
+               table->rows += mono_array_length (tb->generic_params);
+               alloc_table (table, table->rows);
+               for (i = 0; i < mono_array_length (tb->generic_params); ++i) {
+                       guint32 owner = MONO_TYPEORMETHOD_TYPE | (tb->table_idx << MONO_TYPEORMETHOD_BITS);
+
+                       mono_image_get_generic_param_info (
+                               mono_array_get (tb->generic_params, MonoReflectionGenericParam*, i), owner, assembly);
+               }
+       }
+
+       mono_image_add_decl_security (assembly, 
+               mono_metadata_make_token (MONO_TABLE_TYPEDEF, tb->table_idx), tb->permissions);
+
+       if (tb->subtypes) {
+               MonoDynamicTable *ntable;
+               
+               ntable = &assembly->tables [MONO_TABLE_NESTEDCLASS];
+               ntable->rows += mono_array_length (tb->subtypes);
+               alloc_table (ntable, ntable->rows);
+               values = ntable->values + ntable->next_idx * MONO_NESTED_CLASS_SIZE;
+
+               for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
+                       MonoReflectionTypeBuilder *subtype = mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i);
+
+                       values [MONO_NESTED_CLASS_NESTED] = subtype->table_idx;
+                       values [MONO_NESTED_CLASS_ENCLOSING] = tb->table_idx;
+                       /*g_print ("nesting %s (%d) in %s (%d) (rows %d/%d)\n",
+                               mono_string_to_utf8 (subtype->name), subtype->table_idx,
+                               mono_string_to_utf8 (tb->name), tb->table_idx,
+                               ntable->next_idx, ntable->rows);*/
+                       values += MONO_NESTED_CLASS_SIZE;
+                       ntable->next_idx++;
+               }
+       }
+
+       return TRUE;
+}
+
+
+/*
+ * mono_image_build_metadata() will fill the info in all the needed metadata tables
+ * for the modulebuilder @moduleb.
+ * At the end of the process, method and field tokens are fixed up and the 
+ * on-disk compressed metadata representation is created.
+ * Return TRUE on success, or FALSE on failure and sets @error
+ */
+gboolean
+mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb, MonoError *error)
+{
+       MonoDynamicTable *table;
+       MonoDynamicImage *assembly;
+       MonoReflectionAssemblyBuilder *assemblyb;
+       MonoDomain *domain;
+       MonoPtrArray types;
+       guint32 *values;
+       int i, j;
+
+       mono_error_init (error);
+
+       assemblyb = moduleb->assemblyb;
+       assembly = moduleb->dynamic_image;
+       domain = mono_object_domain (assemblyb);
+
+       if (assembly->text_rva)
+               return TRUE;
+
+       assembly->text_rva = START_TEXT_RVA;
+
+       if (moduleb->is_main) {
+               mono_image_emit_manifest (moduleb, error);
+               return_val_if_nok (error, FALSE);
+       }
+
+       table = &assembly->tables [MONO_TABLE_TYPEDEF];
+       table->rows = 1; /* .<Module> */
+       table->next_idx++;
+       alloc_table (table, table->rows);
+       /*
+        * Set the first entry.
+        */
+       values = table->values + table->columns;
+       values [MONO_TYPEDEF_FLAGS] = 0;
+       values [MONO_TYPEDEF_NAME] = string_heap_insert (&assembly->sheap, "<Module>") ;
+       values [MONO_TYPEDEF_NAMESPACE] = string_heap_insert (&assembly->sheap, "") ;
+       values [MONO_TYPEDEF_EXTENDS] = 0;
+       values [MONO_TYPEDEF_FIELD_LIST] = 1;
+       values [MONO_TYPEDEF_METHOD_LIST] = 1;
+
+       /* 
+        * handle global methods 
+        * FIXME: test what to do when global methods are defined in multiple modules.
+        */
+       if (moduleb->global_methods) {
+               table = &assembly->tables [MONO_TABLE_METHOD];
+               table->rows += mono_array_length (moduleb->global_methods);
+               alloc_table (table, table->rows);
+               for (i = 0; i < mono_array_length (moduleb->global_methods); ++i) {
+                       if (!mono_image_get_method_info (
+                                   mono_array_get (moduleb->global_methods, MonoReflectionMethodBuilder*, i), assembly, error))
+                               goto leave;
+               }
+       }
+       if (moduleb->global_fields) {
+               table = &assembly->tables [MONO_TABLE_FIELD];
+               table->rows += mono_array_length (moduleb->global_fields);
+               alloc_table (table, table->rows);
+               for (i = 0; i < mono_array_length (moduleb->global_fields); ++i) {
+                       mono_image_get_field_info (
+                               mono_array_get (moduleb->global_fields, MonoReflectionFieldBuilder*, i), assembly,
+                               error);
+                       if (!is_ok (error))
+                               goto leave;
+               }
+       }
+
+       table = &assembly->tables [MONO_TABLE_MODULE];
+       alloc_table (table, 1);
+       mono_image_fill_module_table (domain, moduleb, assembly, error);
+       if (!is_ok (error))
+               goto leave;
+
+       /* Collect all types into a list sorted by their table_idx */
+       mono_ptr_array_init (types, moduleb->num_types, MONO_ROOT_SOURCE_REFLECTION, "dynamic module types list");
+
+       if (moduleb->types)
+               for (i = 0; i < moduleb->num_types; ++i) {
+                       MonoReflectionTypeBuilder *type = mono_array_get (moduleb->types, MonoReflectionTypeBuilder*, i);
+                       collect_types (&types, type);
+               }
+
+       mono_ptr_array_sort (types, (int (*)(const void *, const void *))compare_types_by_table_idx);
+       table = &assembly->tables [MONO_TABLE_TYPEDEF];
+       table->rows += mono_ptr_array_size (types);
+       alloc_table (table, table->rows);
+
+       /*
+        * Emit type names + namespaces at one place inside the string heap,
+        * so load_class_names () needs to touch fewer pages.
+        */
+       for (i = 0; i < mono_ptr_array_size (types); ++i) {
+               MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_ptr_array_get (types, i);
+               string_heap_insert_mstring (&assembly->sheap, tb->nspace, error);
+               if (!is_ok (error))
+                       goto leave_types;
+       }
+       for (i = 0; i < mono_ptr_array_size (types); ++i) {
+               MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_ptr_array_get (types, i);
+               string_heap_insert_mstring (&assembly->sheap, tb->name, error);
+               if (!is_ok (error))
+                       goto leave_types;
+       }
+
+       for (i = 0; i < mono_ptr_array_size (types); ++i) {
+               MonoReflectionTypeBuilder *type = (MonoReflectionTypeBuilder *)mono_ptr_array_get (types, i);
+               if (!mono_image_get_type_info (domain, type, assembly, error))
+                       goto leave_types;
+       }
+
+       /* 
+        * table->rows is already set above and in mono_image_fill_module_table.
+        */
+       /* add all the custom attributes at the end, once all the indexes are stable */
+       if (!mono_image_add_cattrs (assembly, 1, MONO_CUSTOM_ATTR_ASSEMBLY, assemblyb->cattrs, error))
+               goto leave_types;
+
+       /* CAS assembly permissions */
+       if (assemblyb->permissions_minimum)
+               mono_image_add_decl_security (assembly, mono_metadata_make_token (MONO_TABLE_ASSEMBLY, 1), assemblyb->permissions_minimum);
+       if (assemblyb->permissions_optional)
+               mono_image_add_decl_security (assembly, mono_metadata_make_token (MONO_TABLE_ASSEMBLY, 1), assemblyb->permissions_optional);
+       if (assemblyb->permissions_refused)
+               mono_image_add_decl_security (assembly, mono_metadata_make_token (MONO_TABLE_ASSEMBLY, 1), assemblyb->permissions_refused);
+
+       if (!module_add_cattrs (assembly, moduleb, error))
+               goto leave_types;
+
+       /* fixup tokens */
+       mono_g_hash_table_foreach (assembly->token_fixups, (GHFunc)fixup_method, assembly);
+
+       /* Create the MethodImpl table.  We do this after emitting all methods so we already know
+        * the final tokens and don't need another fixup pass. */
+
+       if (moduleb->global_methods) {
+               for (i = 0; i < mono_array_length (moduleb->global_methods); ++i) {
+                       MonoReflectionMethodBuilder *mb = mono_array_get (
+                               moduleb->global_methods, MonoReflectionMethodBuilder*, i);
+                       if (!mono_image_add_methodimpl (assembly, mb, error))
+                               goto leave_types;
+               }
+       }
+
+       for (i = 0; i < mono_ptr_array_size (types); ++i) {
+               MonoReflectionTypeBuilder *type = (MonoReflectionTypeBuilder *)mono_ptr_array_get (types, i);
+               if (type->methods) {
+                       for (j = 0; j < type->num_methods; ++j) {
+                               MonoReflectionMethodBuilder *mb = mono_array_get (
+                                       type->methods, MonoReflectionMethodBuilder*, j);
+
+                               if (!mono_image_add_methodimpl (assembly, mb, error))
+                                       goto leave_types;
+                       }
+               }
+       }
+
+       fixup_cattrs (assembly);
+
+leave_types:
+       mono_ptr_array_destroy (types);
+leave:
+
+       return mono_error_ok (error);
+}
+
+#else /* DISABLE_REFLECTION_EMIT_SAVE */
+
+gboolean
+mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb, MonoError *error)
+{
+       g_error ("This mono runtime was configured with --enable-minimal=reflection_emit_save, so saving of dynamic assemblies is not supported.");
+}
+
+#endif /* DISABLE_REFLECTION_EMIT_SAVE */
+
+#ifndef DISABLE_REFLECTION_EMIT_SAVE
+
+static int
+calc_section_size (MonoDynamicImage *assembly)
+{
+       int nsections = 0;
+
+       /* alignment constraints */
+       mono_image_add_stream_zero (&assembly->code, 4 - (assembly->code.index % 4));
+       g_assert ((assembly->code.index % 4) == 0);
+       assembly->meta_size += 3;
+       assembly->meta_size &= ~3;
+       mono_image_add_stream_zero (&assembly->resources, 4 - (assembly->resources.index % 4));
+       g_assert ((assembly->resources.index % 4) == 0);
+
+       assembly->sections [MONO_SECTION_TEXT].size = assembly->meta_size + assembly->code.index + assembly->resources.index + assembly->strong_name_size;
+       assembly->sections [MONO_SECTION_TEXT].attrs = SECT_FLAGS_HAS_CODE | SECT_FLAGS_MEM_EXECUTE | SECT_FLAGS_MEM_READ;
+       nsections++;
+
+       if (assembly->win32_res) {
+               guint32 res_size = (assembly->win32_res_size + 3) & ~3;
+
+               assembly->sections [MONO_SECTION_RSRC].size = res_size;
+               assembly->sections [MONO_SECTION_RSRC].attrs = SECT_FLAGS_HAS_INITIALIZED_DATA | SECT_FLAGS_MEM_READ;
+               nsections++;
+       }
+
+       assembly->sections [MONO_SECTION_RELOC].size = 12;
+       assembly->sections [MONO_SECTION_RELOC].attrs = SECT_FLAGS_MEM_READ | SECT_FLAGS_MEM_DISCARDABLE | SECT_FLAGS_HAS_INITIALIZED_DATA;
+       nsections++;
+
+       return nsections;
+}
+
+typedef struct {
+       guint32 id;
+       guint32 offset;
+       GSList *children;
+       MonoReflectionWin32Resource *win32_res; /* Only for leaf nodes */
+} ResTreeNode;
+
+static int
+resource_tree_compare_by_id (gconstpointer a, gconstpointer b)
+{
+       ResTreeNode *t1 = (ResTreeNode*)a;
+       ResTreeNode *t2 = (ResTreeNode*)b;
+
+       return t1->id - t2->id;
+}
+
+/*
+ * resource_tree_create:
+ *
+ *  Organize the resources into a resource tree.
+ */
+static ResTreeNode *
+resource_tree_create (MonoArray *win32_resources)
+{
+       ResTreeNode *tree, *res_node, *type_node, *lang_node;
+       GSList *l;
+       int i;
+
+       tree = g_new0 (ResTreeNode, 1);
+       
+       for (i = 0; i < mono_array_length (win32_resources); ++i) {
+               MonoReflectionWin32Resource *win32_res =
+                       (MonoReflectionWin32Resource*)mono_array_addr (win32_resources, MonoReflectionWin32Resource, i);
+
+               /* Create node */
+
+               /* FIXME: BUG: this stores managed references in unmanaged memory */
+               lang_node = g_new0 (ResTreeNode, 1);
+               lang_node->id = win32_res->lang_id;
+               lang_node->win32_res = win32_res;
+
+               /* Create type node if neccesary */
+               type_node = NULL;
+               for (l = tree->children; l; l = l->next)
+                       if (((ResTreeNode*)(l->data))->id == win32_res->res_type) {
+                               type_node = (ResTreeNode*)l->data;
+                               break;
+                       }
+
+               if (!type_node) {
+                       type_node = g_new0 (ResTreeNode, 1);
+                       type_node->id = win32_res->res_type;
+
+                       /* 
+                        * The resource types have to be sorted otherwise
+                        * Windows Explorer can't display the version information.
+                        */
+                       tree->children = g_slist_insert_sorted (tree->children, 
+                               type_node, resource_tree_compare_by_id);
+               }
+
+               /* Create res node if neccesary */
+               res_node = NULL;
+               for (l = type_node->children; l; l = l->next)
+                       if (((ResTreeNode*)(l->data))->id == win32_res->res_id) {
+                               res_node = (ResTreeNode*)l->data;
+                               break;
+                       }
+
+               if (!res_node) {
+                       res_node = g_new0 (ResTreeNode, 1);
+                       res_node->id = win32_res->res_id;
+                       type_node->children = g_slist_append (type_node->children, res_node);
+               }
+
+               res_node->children = g_slist_append (res_node->children, lang_node);
+       }
+
+       return tree;
+}
+
+/*
+ * resource_tree_encode:
+ * 
+ *   Encode the resource tree into the format used in the PE file.
+ */
+static void
+resource_tree_encode (ResTreeNode *node, char *begin, char *p, char **endbuf)
+{
+       char *entries;
+       MonoPEResourceDir dir;
+       MonoPEResourceDirEntry dir_entry;
+       MonoPEResourceDataEntry data_entry;
+       GSList *l;
+       guint32 res_id_entries;
+
+       /*
+        * For the format of the resource directory, see the article
+        * "An In-Depth Look into the Win32 Portable Executable File Format" by
+        * Matt Pietrek
+        */
+
+       memset (&dir, 0, sizeof (dir));
+       memset (&dir_entry, 0, sizeof (dir_entry));
+       memset (&data_entry, 0, sizeof (data_entry));
+
+       g_assert (sizeof (dir) == 16);
+       g_assert (sizeof (dir_entry) == 8);
+       g_assert (sizeof (data_entry) == 16);
+
+       node->offset = p - begin;
+
+       /* IMAGE_RESOURCE_DIRECTORY */
+       res_id_entries = g_slist_length (node->children);
+       dir.res_id_entries = GUINT16_TO_LE (res_id_entries);
+
+       memcpy (p, &dir, sizeof (dir));
+       p += sizeof (dir);
+
+       /* Reserve space for entries */
+       entries = p;
+       p += sizeof (dir_entry) * res_id_entries;
+
+       /* Write children */
+       for (l = node->children; l; l = l->next) {
+               ResTreeNode *child = (ResTreeNode*)l->data;
+
+               if (child->win32_res) {
+                       guint32 size;
+
+                       child->offset = p - begin;
+
+                       /* IMAGE_RESOURCE_DATA_ENTRY */
+                       data_entry.rde_data_offset = GUINT32_TO_LE (p - begin + sizeof (data_entry));
+                       size = mono_array_length (child->win32_res->res_data);
+                       data_entry.rde_size = GUINT32_TO_LE (size);
+
+                       memcpy (p, &data_entry, sizeof (data_entry));
+                       p += sizeof (data_entry);
+
+                       memcpy (p, mono_array_addr (child->win32_res->res_data, char, 0), size);
+                       p += size;
+               } else {
+                       resource_tree_encode (child, begin, p, &p);
+               }
+       }
+
+       /* IMAGE_RESOURCE_ENTRY */
+       for (l = node->children; l; l = l->next) {
+               ResTreeNode *child = (ResTreeNode*)l->data;
+
+               MONO_PE_RES_DIR_ENTRY_SET_NAME (dir_entry, FALSE, child->id);
+               MONO_PE_RES_DIR_ENTRY_SET_DIR (dir_entry, !child->win32_res, child->offset);
+
+               memcpy (entries, &dir_entry, sizeof (dir_entry));
+               entries += sizeof (dir_entry);
+       }
+
+       *endbuf = p;
+}
+
+static void
+resource_tree_free (ResTreeNode * node)
+{
+       GSList * list;
+       for (list = node->children; list; list = list->next)
+               resource_tree_free ((ResTreeNode*)list->data);
+       g_slist_free(node->children);
+       g_free (node);
+}
+
+static void
+assembly_add_win32_resources (MonoDynamicImage *assembly, MonoReflectionAssemblyBuilder *assemblyb)
+{
+       char *buf;
+       char *p;
+       guint32 size, i;
+       MonoReflectionWin32Resource *win32_res;
+       ResTreeNode *tree;
+
+       if (!assemblyb->win32_resources)
+               return;
+
+       /*
+        * Resources are stored in a three level tree inside the PE file.
+        * - level one contains a node for each type of resource
+        * - level two contains a node for each resource
+        * - level three contains a node for each instance of a resource for a
+        *   specific language.
+        */
+
+       tree = resource_tree_create (assemblyb->win32_resources);
+
+       /* Estimate the size of the encoded tree */
+       size = 0;
+       for (i = 0; i < mono_array_length (assemblyb->win32_resources); ++i) {
+               win32_res = (MonoReflectionWin32Resource*)mono_array_addr (assemblyb->win32_resources, MonoReflectionWin32Resource, i);
+               size += mono_array_length (win32_res->res_data);
+       }
+       /* Directory structure */
+       size += mono_array_length (assemblyb->win32_resources) * 256;
+       p = buf = (char *)g_malloc (size);
+
+       resource_tree_encode (tree, p, p, &p);
+
+       g_assert (p - buf <= size);
+
+       assembly->win32_res = (char *)g_malloc (p - buf);
+       assembly->win32_res_size = p - buf;
+       memcpy (assembly->win32_res, buf, p - buf);
+
+       g_free (buf);
+       resource_tree_free (tree);
+}
+
+static void
+fixup_resource_directory (char *res_section, char *p, guint32 rva)
+{
+       MonoPEResourceDir *dir = (MonoPEResourceDir*)p;
+       int i;
+
+       p += sizeof (MonoPEResourceDir);
+       for (i = 0; i < GUINT16_FROM_LE (dir->res_named_entries) + GUINT16_FROM_LE (dir->res_id_entries); ++i) {
+               MonoPEResourceDirEntry *dir_entry = (MonoPEResourceDirEntry*)p;
+               char *child = res_section + MONO_PE_RES_DIR_ENTRY_DIR_OFFSET (*dir_entry);
+               if (MONO_PE_RES_DIR_ENTRY_IS_DIR (*dir_entry)) {
+                       fixup_resource_directory (res_section, child, rva);
+               } else {
+                       MonoPEResourceDataEntry *data_entry = (MonoPEResourceDataEntry*)child;
+                       data_entry->rde_data_offset = GUINT32_TO_LE (GUINT32_FROM_LE (data_entry->rde_data_offset) + rva);
+               }
+
+               p += sizeof (MonoPEResourceDirEntry);
+       }
+}
+
+static void
+checked_write_file (HANDLE f, gconstpointer buffer, guint32 numbytes)
+{
+       guint32 dummy;
+       if (!WriteFile (f, buffer, numbytes, &dummy, NULL))
+               g_error ("WriteFile returned %d\n", GetLastError ());
+}
+
+/*
+ * mono_image_create_pefile:
+ * @mb: a module builder object
+ * 
+ * This function creates the PE-COFF header, the image sections, the CLI header  * etc. all the data is written in
+ * assembly->pefile where it can be easily retrieved later in chunks.
+ */
+gboolean
+mono_image_create_pefile (MonoReflectionModuleBuilder *mb, HANDLE file, MonoError *error)
+{
+       MonoMSDOSHeader *msdos;
+       MonoDotNetHeader *header;
+       MonoSectionTable *section;
+       MonoCLIHeader *cli_header;
+       guint32 size, image_size, virtual_base, text_offset;
+       guint32 header_start, section_start, file_offset, virtual_offset;
+       MonoDynamicImage *assembly;
+       MonoReflectionAssemblyBuilder *assemblyb;
+       MonoDynamicStream pefile_stream = {0};
+       MonoDynamicStream *pefile = &pefile_stream;
+       int i, nsections;
+       guint32 *rva, value;
+       guchar *p;
+       static const unsigned char msheader[] = {
+               0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00,  0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
+               0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+               0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd,  0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68,
+               0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72,  0x61, 0x6d, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f,
+               0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6e,  0x20, 0x69, 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20,
+               0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a,  0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+       };
+
+       mono_error_init (error);
+
+       assemblyb = mb->assemblyb;
+
+       mono_reflection_dynimage_basic_init (assemblyb);
+       assembly = mb->dynamic_image;
+
+       assembly->pe_kind = assemblyb->pe_kind;
+       assembly->machine = assemblyb->machine;
+       ((MonoDynamicImage*)assemblyb->dynamic_assembly->assembly.image)->pe_kind = assemblyb->pe_kind;
+       ((MonoDynamicImage*)assemblyb->dynamic_assembly->assembly.image)->machine = assemblyb->machine;
+       
+       if (!mono_image_build_metadata (mb, error))
+               return FALSE;
+       
+
+       if (mb->is_main && assemblyb->resources) {
+               int len = mono_array_length (assemblyb->resources);
+               for (i = 0; i < len; ++i) {
+                       if (!assembly_add_resource (mb, assembly, (MonoReflectionResource*)mono_array_addr (assemblyb->resources, MonoReflectionResource, i), error))
+                               return FALSE;
+               }
+       }
+
+       if (mb->resources) {
+               int len = mono_array_length (mb->resources);
+               for (i = 0; i < len; ++i) {
+                       if (!assembly_add_resource (mb, assembly, (MonoReflectionResource*)mono_array_addr (mb->resources, MonoReflectionResource, i), error))
+                               return FALSE;
+               }
+       }
+
+       if (!build_compressed_metadata (assembly, error))
+               return FALSE;
+
+       if (mb->is_main)
+               assembly_add_win32_resources (assembly, assemblyb);
+
+       nsections = calc_section_size (assembly);
+       
+       /* The DOS header and stub */
+       g_assert (sizeof (MonoMSDOSHeader) == sizeof (msheader));
+       mono_image_add_stream_data (pefile, (char*)msheader, sizeof (msheader));
+
+       /* the dotnet header */
+       header_start = mono_image_add_stream_zero (pefile, sizeof (MonoDotNetHeader));
+
+       /* the section tables */
+       section_start = mono_image_add_stream_zero (pefile, sizeof (MonoSectionTable) * nsections);
+
+       file_offset = section_start + sizeof (MonoSectionTable) * nsections;
+       virtual_offset = VIRT_ALIGN;
+       image_size = 0;
+
+       for (i = 0; i < MONO_SECTION_MAX; ++i) {
+               if (!assembly->sections [i].size)
+                       continue;
+               /* align offsets */
+               file_offset += FILE_ALIGN - 1;
+               file_offset &= ~(FILE_ALIGN - 1);
+               virtual_offset += VIRT_ALIGN - 1;
+               virtual_offset &= ~(VIRT_ALIGN - 1);
+
+               assembly->sections [i].offset = file_offset;
+               assembly->sections [i].rva = virtual_offset;
+
+               file_offset += assembly->sections [i].size;
+               virtual_offset += assembly->sections [i].size;
+               image_size += (assembly->sections [i].size + VIRT_ALIGN - 1) & ~(VIRT_ALIGN - 1);
+       }
+
+       file_offset += FILE_ALIGN - 1;
+       file_offset &= ~(FILE_ALIGN - 1);
+
+       image_size += section_start + sizeof (MonoSectionTable) * nsections;
+
+       /* back-patch info */
+       msdos = (MonoMSDOSHeader*)pefile->data;
+       msdos->pe_offset = GUINT32_FROM_LE (sizeof (MonoMSDOSHeader));
+
+       header = (MonoDotNetHeader*)(pefile->data + header_start);
+       header->pesig [0] = 'P';
+       header->pesig [1] = 'E';
+       
+       header->coff.coff_machine = GUINT16_FROM_LE (assemblyb->machine);
+       header->coff.coff_sections = GUINT16_FROM_LE (nsections);
+       header->coff.coff_time = GUINT32_FROM_LE (time (NULL));
+       header->coff.coff_opt_header_size = GUINT16_FROM_LE (sizeof (MonoDotNetHeader) - sizeof (MonoCOFFHeader) - 4);
+       if (assemblyb->pekind == 1) {
+               /* it's a dll */
+               header->coff.coff_attributes = GUINT16_FROM_LE (0x210e);
+       } else {
+               /* it's an exe */
+               header->coff.coff_attributes = GUINT16_FROM_LE (0x010e);
+       }
+
+       virtual_base = 0x400000; /* FIXME: 0x10000000 if a DLL */
+
+       header->pe.pe_magic = GUINT16_FROM_LE (0x10B);
+       header->pe.pe_major = 6;
+       header->pe.pe_minor = 0;
+       size = assembly->sections [MONO_SECTION_TEXT].size;
+       size += FILE_ALIGN - 1;
+       size &= ~(FILE_ALIGN - 1);
+       header->pe.pe_code_size = GUINT32_FROM_LE(size);
+       size = assembly->sections [MONO_SECTION_RSRC].size;
+       size += FILE_ALIGN - 1;
+       size &= ~(FILE_ALIGN - 1);
+       header->pe.pe_data_size = GUINT32_FROM_LE(size);
+       g_assert (START_TEXT_RVA == assembly->sections [MONO_SECTION_TEXT].rva);
+       header->pe.pe_rva_code_base = GUINT32_FROM_LE (assembly->sections [MONO_SECTION_TEXT].rva);
+       header->pe.pe_rva_data_base = GUINT32_FROM_LE (assembly->sections [MONO_SECTION_RSRC].rva);
+       /* pe_rva_entry_point always at the beginning of the text section */
+       header->pe.pe_rva_entry_point = GUINT32_FROM_LE (assembly->sections [MONO_SECTION_TEXT].rva);
+
+       header->nt.pe_image_base = GUINT32_FROM_LE (virtual_base);
+       header->nt.pe_section_align = GUINT32_FROM_LE (VIRT_ALIGN);
+       header->nt.pe_file_alignment = GUINT32_FROM_LE (FILE_ALIGN);
+       header->nt.pe_os_major = GUINT16_FROM_LE (4);
+       header->nt.pe_os_minor = GUINT16_FROM_LE (0);
+       header->nt.pe_subsys_major = GUINT16_FROM_LE (4);
+       size = section_start;
+       size += FILE_ALIGN - 1;
+       size &= ~(FILE_ALIGN - 1);
+       header->nt.pe_header_size = GUINT32_FROM_LE (size);
+       size = image_size;
+       size += VIRT_ALIGN - 1;
+       size &= ~(VIRT_ALIGN - 1);
+       header->nt.pe_image_size = GUINT32_FROM_LE (size);
+
+       /*
+       // Translate the PEFileKind value to the value expected by the Windows loader
+       */
+       {
+               short kind;
+
+               /*
+               // PEFileKinds.Dll == 1
+               // PEFileKinds.ConsoleApplication == 2
+               // PEFileKinds.WindowApplication == 3
+               //
+               // need to get:
+               //     IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem.
+                //     IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem.
+               */
+               if (assemblyb->pekind == 3)
+                       kind = 2;
+               else
+                       kind = 3;
+               
+               header->nt.pe_subsys_required = GUINT16_FROM_LE (kind);
+       }    
+       header->nt.pe_stack_reserve = GUINT32_FROM_LE (0x00100000);
+       header->nt.pe_stack_commit = GUINT32_FROM_LE (0x00001000);
+       header->nt.pe_heap_reserve = GUINT32_FROM_LE (0x00100000);
+       header->nt.pe_heap_commit = GUINT32_FROM_LE (0x00001000);
+       header->nt.pe_loader_flags = GUINT32_FROM_LE (0);
+       header->nt.pe_data_dir_count = GUINT32_FROM_LE (16);
+
+       /* fill data directory entries */
+
+       header->datadir.pe_resource_table.size = GUINT32_FROM_LE (assembly->sections [MONO_SECTION_RSRC].size);
+       header->datadir.pe_resource_table.rva = GUINT32_FROM_LE (assembly->sections [MONO_SECTION_RSRC].rva);
+
+       header->datadir.pe_reloc_table.size = GUINT32_FROM_LE (assembly->sections [MONO_SECTION_RELOC].size);
+       header->datadir.pe_reloc_table.rva = GUINT32_FROM_LE (assembly->sections [MONO_SECTION_RELOC].rva);
+
+       header->datadir.pe_cli_header.size = GUINT32_FROM_LE (72);
+       header->datadir.pe_cli_header.rva = GUINT32_FROM_LE (assembly->text_rva + assembly->cli_header_offset);
+       header->datadir.pe_iat.size = GUINT32_FROM_LE (8);
+       header->datadir.pe_iat.rva = GUINT32_FROM_LE (assembly->text_rva + assembly->iat_offset);
+       /* patch entrypoint name */
+       if (assemblyb->pekind == 1)
+               memcpy (assembly->code.data + assembly->imp_names_offset + 2, "_CorDllMain", 12);
+       else
+               memcpy (assembly->code.data + assembly->imp_names_offset + 2, "_CorExeMain", 12);
+       /* patch imported function RVA name */
+       rva = (guint32*)(assembly->code.data + assembly->iat_offset);
+       *rva = GUINT32_FROM_LE (assembly->text_rva + assembly->imp_names_offset);
+
+       /* the import table */
+       header->datadir.pe_import_table.size = GUINT32_FROM_LE (79); /* FIXME: magic number? */
+       header->datadir.pe_import_table.rva = GUINT32_FROM_LE (assembly->text_rva + assembly->idt_offset);
+       /* patch imported dll RVA name and other entries in the dir */
+       rva = (guint32*)(assembly->code.data + assembly->idt_offset + G_STRUCT_OFFSET (MonoIDT, name_rva));
+       *rva = GUINT32_FROM_LE (assembly->text_rva + assembly->imp_names_offset + 14); /* 14 is hint+strlen+1 of func name */
+       rva = (guint32*)(assembly->code.data + assembly->idt_offset + G_STRUCT_OFFSET (MonoIDT, import_address_table_rva));
+       *rva = GUINT32_FROM_LE (assembly->text_rva + assembly->iat_offset);
+       rva = (guint32*)(assembly->code.data + assembly->idt_offset + G_STRUCT_OFFSET (MonoIDT, import_lookup_table));
+       *rva = GUINT32_FROM_LE (assembly->text_rva + assembly->ilt_offset);
+
+       p = (guchar*)(assembly->code.data + assembly->ilt_offset);
+       value = (assembly->text_rva + assembly->imp_names_offset);
+       *p++ = (value) & 0xff;
+       *p++ = (value >> 8) & (0xff);
+       *p++ = (value >> 16) & (0xff);
+       *p++ = (value >> 24) & (0xff);
+
+       /* the CLI header info */
+       cli_header = (MonoCLIHeader*)(assembly->code.data + assembly->cli_header_offset);
+       cli_header->ch_size = GUINT32_FROM_LE (72);
+       cli_header->ch_runtime_major = GUINT16_FROM_LE (2);
+       cli_header->ch_runtime_minor = GUINT16_FROM_LE (5);
+       cli_header->ch_flags = GUINT32_FROM_LE (assemblyb->pe_kind);
+       if (assemblyb->entry_point) {
+               guint32 table_idx = 0;
+               if (!strcmp (assemblyb->entry_point->object.vtable->klass->name, "MethodBuilder")) {
+                       MonoReflectionMethodBuilder *methodb = (MonoReflectionMethodBuilder*)assemblyb->entry_point;
+                       table_idx = methodb->table_idx;
+               } else {
+                       table_idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->method_to_table_idx, assemblyb->entry_point->method));
+               }
+               cli_header->ch_entry_point = GUINT32_FROM_LE (table_idx | MONO_TOKEN_METHOD_DEF);
+       } else {
+               cli_header->ch_entry_point = GUINT32_FROM_LE (0);
+       }
+       /* The embedded managed resources */
+       text_offset = assembly->text_rva + assembly->code.index;
+       cli_header->ch_resources.rva = GUINT32_FROM_LE (text_offset);
+       cli_header->ch_resources.size = GUINT32_FROM_LE (assembly->resources.index);
+       text_offset += assembly->resources.index;
+       cli_header->ch_metadata.rva = GUINT32_FROM_LE (text_offset);
+       cli_header->ch_metadata.size = GUINT32_FROM_LE (assembly->meta_size);
+       text_offset += assembly->meta_size;
+       if (assembly->strong_name_size) {
+               cli_header->ch_strong_name.rva = GUINT32_FROM_LE (text_offset);
+               cli_header->ch_strong_name.size = GUINT32_FROM_LE (assembly->strong_name_size);
+               text_offset += assembly->strong_name_size;
+       }
+
+       /* write the section tables and section content */
+       section = (MonoSectionTable*)(pefile->data + section_start);
+       for (i = 0; i < MONO_SECTION_MAX; ++i) {
+               static const char section_names [][7] = {
+                       ".text", ".rsrc", ".reloc"
+               };
+               if (!assembly->sections [i].size)
+                       continue;
+               strcpy (section->st_name, section_names [i]);
+               /*g_print ("output section %s (%d), size: %d\n", section->st_name, i, assembly->sections [i].size);*/
+               section->st_virtual_address = GUINT32_FROM_LE (assembly->sections [i].rva);
+               section->st_virtual_size = GUINT32_FROM_LE (assembly->sections [i].size);
+               section->st_raw_data_size = GUINT32_FROM_LE (GUINT32_TO_LE (section->st_virtual_size) + (FILE_ALIGN - 1));
+               section->st_raw_data_size &= GUINT32_FROM_LE (~(FILE_ALIGN - 1));
+               section->st_raw_data_ptr = GUINT32_FROM_LE (assembly->sections [i].offset);
+               section->st_flags = GUINT32_FROM_LE (assembly->sections [i].attrs);
+               section ++;
+       }
+       
+       checked_write_file (file, pefile->data, pefile->index);
+       
+       mono_dynamic_stream_reset (pefile);
+       
+       for (i = 0; i < MONO_SECTION_MAX; ++i) {
+               if (!assembly->sections [i].size)
+                       continue;
+               
+               if (SetFilePointer (file, assembly->sections [i].offset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
+                       g_error ("SetFilePointer returned %d\n", GetLastError ());
+               
+               switch (i) {
+               case MONO_SECTION_TEXT:
+                       /* patch entry point */
+                       p = (guchar*)(assembly->code.data + 2);
+                       value = (virtual_base + assembly->text_rva + assembly->iat_offset);
+                       *p++ = (value) & 0xff;
+                       *p++ = (value >> 8) & 0xff;
+                       *p++ = (value >> 16) & 0xff;
+                       *p++ = (value >> 24) & 0xff;
+               
+                       checked_write_file (file, assembly->code.data, assembly->code.index);
+                       checked_write_file (file, assembly->resources.data, assembly->resources.index);
+                       checked_write_file (file, assembly->image.raw_metadata, assembly->meta_size);
+                       checked_write_file (file, assembly->strong_name, assembly->strong_name_size);
+                               
+
+                       g_free (assembly->image.raw_metadata);
+                       break;
+               case MONO_SECTION_RELOC: {
+                       struct {
+                               guint32 page_rva;
+                               guint32 block_size;
+                               guint16 type_and_offset;
+                               guint16 term;
+                       } reloc;
+                       
+                       g_assert (sizeof (reloc) == 12);
+                       
+                       reloc.page_rva = GUINT32_FROM_LE (assembly->text_rva);
+                       reloc.block_size = GUINT32_FROM_LE (12);
+                       
+                       /* 
+                        * the entrypoint is always at the start of the text section 
+                        * 3 is IMAGE_REL_BASED_HIGHLOW
+                        * 2 is patch_size_rva - text_rva
+                        */
+                       reloc.type_and_offset = GUINT16_FROM_LE ((3 << 12) + (2));
+                       reloc.term = 0;
+                       
+                       checked_write_file (file, &reloc, sizeof (reloc));
+                       
+                       break;
+               }
+               case MONO_SECTION_RSRC:
+                       if (assembly->win32_res) {
+
+                               /* Fixup the offsets in the IMAGE_RESOURCE_DATA_ENTRY structures */
+                               fixup_resource_directory (assembly->win32_res, assembly->win32_res, assembly->sections [i].rva);
+                               checked_write_file (file, assembly->win32_res, assembly->win32_res_size);
+                       }
+                       break;
+               default:
+                       g_assert_not_reached ();
+               }
+       }
+       
+       /* check that the file is properly padded */
+       if (SetFilePointer (file, file_offset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
+               g_error ("SetFilePointer returned %d\n", GetLastError ());
+       if (! SetEndOfFile (file))
+               g_error ("SetEndOfFile returned %d\n", GetLastError ());
+       
+       mono_dynamic_stream_reset (&assembly->code);
+       mono_dynamic_stream_reset (&assembly->us);
+       mono_dynamic_stream_reset (&assembly->blob);
+       mono_dynamic_stream_reset (&assembly->guid);
+       mono_dynamic_stream_reset (&assembly->sheap);
+
+       g_hash_table_foreach (assembly->blob_cache, (GHFunc)g_free, NULL);
+       g_hash_table_destroy (assembly->blob_cache);
+       assembly->blob_cache = NULL;
+
+       return TRUE;
+}
+
+#else /* DISABLE_REFLECTION_EMIT_SAVE */
+
+gboolean
+mono_image_create_pefile (MonoReflectionModuleBuilder *mb, HANDLE file, MonoError *error)
+{
+       g_assert_not_reached ();
+}
+
+#endif /* DISABLE_REFLECTION_EMIT_SAVE */
+
diff --git a/mono/metadata/sre.c b/mono/metadata/sre.c
new file mode 100644 (file)
index 0000000..50d7635
--- /dev/null
@@ -0,0 +1,5432 @@
+/*
+ * sre.c: Routines for creating an image at runtime
+ *   and related System.Reflection.Emit icalls
+ *   
+ * 
+ * Author:
+ *   Paolo Molaro (lupus@ximian.com)
+ *
+ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
+ * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
+ * Copyright 2011 Rodrigo Kumpera
+ * 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>
+#include "mono/metadata/assembly.h"
+#include "mono/metadata/debug-helpers.h"
+#include "mono/metadata/dynamic-image-internals.h"
+#include "mono/metadata/dynamic-stream-internals.h"
+#include "mono/metadata/exception.h"
+#include "mono/metadata/gc-internals.h"
+#include "mono/metadata/mono-ptr-array.h"
+#include "mono/metadata/object-internals.h"
+#include "mono/metadata/profiler-private.h"
+#include "mono/metadata/reflection-internals.h"
+#include "mono/metadata/reflection-cache.h"
+#include "mono/metadata/sre-internals.h"
+#include "mono/metadata/custom-attrs-internals.h"
+#include "mono/metadata/security-manager.h"
+#include "mono/metadata/security-core-clr.h"
+#include "mono/metadata/tabledefs.h"
+#include "mono/metadata/tokentype.h"
+#include "mono/utils/checked-build.h"
+#include "mono/utils/mono-digest.h"
+
+void
+mono_sre_generic_param_table_entry_free (GenericParamTableEntry *entry)
+{
+       mono_gc_deregister_root ((char*) &entry->gparam);
+       g_free (entry);
+}
+
+
+
+static GENERATE_GET_CLASS_WITH_CACHE (marshal_as_attribute, System.Runtime.InteropServices, MarshalAsAttribute);
+
+#ifndef DISABLE_REFLECTION_EMIT
+static guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec);
+static guint32 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_open_instance, MonoError *error);
+static guint32 mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtorBuilder *cb, MonoError *error);
+static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error);
+static gboolean ensure_runtime_vtable (MonoClass *klass, MonoError  *error);
+static guint32 mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method, MonoError *error);
+static void reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb);
+
+static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
+#endif
+
+static char*   type_get_qualified_name (MonoType *type, MonoAssembly *ass);
+static MonoReflectionType *mono_reflection_type_get_underlying_system_type (MonoReflectionType* t, MonoError *error);
+static gboolean is_sre_array (MonoClass *klass);
+static gboolean is_sre_byref (MonoClass *klass);
+static gboolean is_sre_pointer (MonoClass *klass);
+static gboolean is_sre_type_builder (MonoClass *klass);
+static gboolean is_sre_method_builder (MonoClass *klass);
+static gboolean is_sre_field_builder (MonoClass *klass);
+static gboolean is_sr_mono_method (MonoClass *klass);
+static gboolean is_sr_mono_generic_method (MonoClass *klass);
+static gboolean is_sr_mono_generic_cmethod (MonoClass *klass);
+static gboolean is_sr_mono_field (MonoClass *klass);
+
+static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method);
+static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m);
+static MonoMethod * inflate_method (MonoReflectionType *type, MonoObject *obj, MonoError *error);
+
+static guint32 create_typespec (MonoDynamicImage *assembly, MonoType *type);
+
+#define mono_type_array_get_and_resolve(array, index, error) mono_reflection_type_get_handle ((MonoReflectionType*)mono_array_get (array, gpointer, index), error)
+
+static void mono_image_module_basic_init (MonoReflectionModuleBuilder *module);
+
+void
+mono_reflection_emit_init (void)
+{
+       mono_dynamic_images_init ();
+}
+
+static char*
+type_get_fully_qualified_name (MonoType *type)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
+}
+
+static char*
+type_get_qualified_name (MonoType *type, MonoAssembly *ass)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       MonoClass *klass;
+       MonoAssembly *ta;
+
+       klass = mono_class_from_mono_type (type);
+       if (!klass) 
+               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)
+                       /* 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
+                       return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
+       }
+
+       return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
+}
+
+#ifndef DISABLE_REFLECTION_EMIT
+/**
+ * mp_g_alloc:
+ *
+ * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
+ * from the C heap.
+ */
+static gpointer
+image_g_malloc (MonoImage *image, guint size)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       if (image)
+               return mono_image_alloc (image, size);
+       else
+               return g_malloc (size);
+}
+#endif /* !DISABLE_REFLECTION_EMIT */
+
+/**
+ * image_g_alloc0:
+ *
+ * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
+ * from the C heap.
+ */
+gpointer
+mono_image_g_malloc0 (MonoImage *image, guint size)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       if (image)
+               return mono_image_alloc0 (image, size);
+       else
+               return g_malloc0 (size);
+}
+
+/**
+ * image_g_free:
+ * @image: a MonoImage
+ * @ptr: pointer
+ *
+ * If @image is NULL, free @ptr, otherwise do nothing.
+ */
+static void
+image_g_free (MonoImage *image, gpointer ptr)
+{
+       if (image == NULL)
+               g_free (ptr);
+}
+
+#ifndef DISABLE_REFLECTION_EMIT
+static char*
+image_strdup (MonoImage *image, const char *s)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       if (image)
+               return mono_image_strdup (image, s);
+       else
+               return g_strdup (s);
+}
+#endif
+
+#define image_g_new(image,struct_type, n_structs)              \
+    ((struct_type *) image_g_malloc (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
+
+#define image_g_new0(image,struct_type, n_structs)             \
+    ((struct_type *) mono_image_g_malloc0 (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
+
+
+static void
+alloc_table (MonoDynamicTable *table, guint nrows)
+{
+       mono_dynimage_alloc_table (table, nrows);
+}
+
+static guint32
+string_heap_insert (MonoDynamicStream *sh, const char *str)
+{
+       return mono_dynstream_insert_string (sh, str);
+}
+
+static guint32
+string_heap_insert_mstring (MonoDynamicStream *sh, MonoString *str, MonoError *error)
+{
+       return mono_dynstream_insert_mstring (sh, str, error);
+}
+
+static guint32
+mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
+{
+       return mono_dynstream_add_data (stream, data, len);
+}
+
+static guint32
+mono_image_add_stream_zero (MonoDynamicStream *stream, guint32 len)
+{
+       return mono_dynstream_add_zero (stream, len);
+}
+
+static void
+stream_data_align (MonoDynamicStream *stream)
+{
+       mono_dynstream_data_align (stream);
+}
+
+/*
+ * Despite the name, we handle also TypeSpec (with the above helper).
+ */
+static guint32
+mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
+{
+       return mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
+}
+
+/*
+ * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
+ * dest may be misaligned.
+ */
+static void
+swap_with_size (char *dest, const char* val, int len, int nelem) {
+       MONO_REQ_GC_NEUTRAL_MODE;
+#if G_BYTE_ORDER != G_LITTLE_ENDIAN
+       int elem;
+
+       for (elem = 0; elem < nelem; ++elem) {
+               switch (len) {
+               case 1:
+                       *dest = *val;
+                       break;
+               case 2:
+                       dest [0] = val [1];
+                       dest [1] = val [0];
+                       break;
+               case 4:
+                       dest [0] = val [3];
+                       dest [1] = val [2];
+                       dest [2] = val [1];
+                       dest [3] = val [0];
+                       break;
+               case 8:
+                       dest [0] = val [7];
+                       dest [1] = val [6];
+                       dest [2] = val [5];
+                       dest [3] = val [4];
+                       dest [4] = val [3];
+                       dest [5] = val [2];
+                       dest [6] = val [1];
+                       dest [7] = val [0];
+                       break;
+               default:
+                       g_assert_not_reached ();
+               }
+               dest += len;
+               val += len;
+       }
+#else
+       memcpy (dest, val, len * nelem);
+#endif
+}
+
+#ifndef DISABLE_REFLECTION_EMIT
+static MonoClass *
+default_class_from_mono_type (MonoType *type)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       switch (type->type) {
+       case MONO_TYPE_OBJECT:
+               return mono_defaults.object_class;
+       case MONO_TYPE_VOID:
+               return mono_defaults.void_class;
+       case MONO_TYPE_BOOLEAN:
+               return mono_defaults.boolean_class;
+       case MONO_TYPE_CHAR:
+               return mono_defaults.char_class;
+       case MONO_TYPE_I1:
+               return mono_defaults.sbyte_class;
+       case MONO_TYPE_U1:
+               return mono_defaults.byte_class;
+       case MONO_TYPE_I2:
+               return mono_defaults.int16_class;
+       case MONO_TYPE_U2:
+               return mono_defaults.uint16_class;
+       case MONO_TYPE_I4:
+               return mono_defaults.int32_class;
+       case MONO_TYPE_U4:
+               return mono_defaults.uint32_class;
+       case MONO_TYPE_I:
+               return mono_defaults.int_class;
+       case MONO_TYPE_U:
+               return mono_defaults.uint_class;
+       case MONO_TYPE_I8:
+               return mono_defaults.int64_class;
+       case MONO_TYPE_U8:
+               return mono_defaults.uint64_class;
+       case MONO_TYPE_R4:
+               return mono_defaults.single_class;
+       case MONO_TYPE_R8:
+               return mono_defaults.double_class;
+       case MONO_TYPE_STRING:
+               return mono_defaults.string_class;
+       default:
+               g_warning ("default_class_from_mono_type: implement me 0x%02x\n", type->type);
+               g_assert_not_reached ();
+       }
+       
+       return NULL;
+}
+#endif
+
+guint32
+mono_reflection_method_count_clauses (MonoReflectionILGen *ilgen)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       guint32 num_clauses = 0;
+       int i;
+
+       MonoILExceptionInfo *ex_info;
+       for (i = 0; i < mono_array_length (ilgen->ex_handlers); ++i) {
+               ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
+               if (ex_info->handlers)
+                       num_clauses += mono_array_length (ex_info->handlers);
+               else
+                       num_clauses++;
+       }
+
+       return num_clauses;
+}
+
+#ifndef DISABLE_REFLECTION_EMIT
+static MonoExceptionClause*
+method_encode_clauses (MonoImage *image, MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, guint32 num_clauses, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       mono_error_init (error);
+
+       MonoExceptionClause *clauses;
+       MonoExceptionClause *clause;
+       MonoILExceptionInfo *ex_info;
+       MonoILExceptionBlock *ex_block;
+       guint32 finally_start;
+       int i, j, clause_index;;
+
+       clauses = image_g_new0 (image, MonoExceptionClause, num_clauses);
+
+       clause_index = 0;
+       for (i = mono_array_length (ilgen->ex_handlers) - 1; i >= 0; --i) {
+               ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
+               finally_start = ex_info->start + ex_info->len;
+               if (!ex_info->handlers)
+                       continue;
+               for (j = 0; j < mono_array_length (ex_info->handlers); ++j) {
+                       ex_block = (MonoILExceptionBlock*)mono_array_addr (ex_info->handlers, MonoILExceptionBlock, j);
+                       clause = &(clauses [clause_index]);
+
+                       clause->flags = ex_block->type;
+                       clause->try_offset = ex_info->start;
+
+                       if (ex_block->type == MONO_EXCEPTION_CLAUSE_FINALLY)
+                               clause->try_len = finally_start - ex_info->start;
+                       else
+                               clause->try_len = ex_info->len;
+                       clause->handler_offset = ex_block->start;
+                       clause->handler_len = ex_block->len;
+                       if (ex_block->extype) {
+                               MonoType *extype = mono_reflection_type_get_handle ((MonoReflectionType*)ex_block->extype, error);
+
+                               if (!is_ok (error)) {
+                                       image_g_free (image, clauses);
+                                       return NULL;
+                               }
+                               clause->data.catch_class = mono_class_from_mono_type (extype);
+                       } else {
+                               if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
+                                       clause->data.filter_offset = ex_block->filter_offset;
+                               else
+                                       clause->data.filter_offset = 0;
+                       }
+                       finally_start = ex_block->start + ex_block->len;
+
+                       clause_index ++;
+               }
+       }
+
+       return clauses;
+}
+#endif /* !DISABLE_REFLECTION_EMIT */
+
+#ifndef DISABLE_REFLECTION_EMIT
+/*
+ * LOCKING: Acquires the loader lock. 
+ */
+static void
+mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       MonoCustomAttrInfo *ainfo, *tmp;
+
+       if (!cattrs || !mono_array_length (cattrs))
+               return;
+
+       ainfo = mono_custom_attrs_from_builders (image, image, cattrs);
+
+       mono_loader_lock ();
+       tmp = (MonoCustomAttrInfo *)mono_image_property_lookup (image, obj, MONO_PROP_DYNAMIC_CATTR);
+       if (tmp)
+               mono_custom_attrs_free (tmp);
+       mono_image_property_insert (image, obj, MONO_PROP_DYNAMIC_CATTR, ainfo);
+       mono_loader_unlock ();
+
+}
+#endif
+
+
+guint32
+mono_reflection_resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       MonoDynamicTable *table;
+       guint32 token;
+       guint32 *values;
+       guint32 cols [MONO_ASSEMBLY_SIZE];
+       const char *pubkey;
+       guint32 publen;
+
+       if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, image))))
+               return token;
+
+       if (assembly_is_dynamic (image->assembly) && (image->assembly == assembly->image.assembly)) {
+               table = &assembly->tables [MONO_TABLE_MODULEREF];
+               token = table->next_idx ++;
+               table->rows ++;
+               alloc_table (table, table->rows);
+               values = table->values + token * MONO_MODULEREF_SIZE;
+               values [MONO_MODULEREF_NAME] = string_heap_insert (&assembly->sheap, image->module_name);
+
+               token <<= MONO_RESOLUTION_SCOPE_BITS;
+               token |= MONO_RESOLUTION_SCOPE_MODULEREF;
+               g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
+
+               return token;
+       }
+       
+       if (assembly_is_dynamic (image->assembly))
+               /* FIXME: */
+               memset (cols, 0, sizeof (cols));
+       else {
+               /* image->assembly->image is the manifest module */
+               image = image->assembly->image;
+               mono_metadata_decode_row (&image->tables [MONO_TABLE_ASSEMBLY], 0, cols, MONO_ASSEMBLY_SIZE);
+       }
+
+       table = &assembly->tables [MONO_TABLE_ASSEMBLYREF];
+       token = table->next_idx ++;
+       table->rows ++;
+       alloc_table (table, table->rows);
+       values = table->values + token * MONO_ASSEMBLYREF_SIZE;
+       values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, image->assembly_name);
+       values [MONO_ASSEMBLYREF_MAJOR_VERSION] = cols [MONO_ASSEMBLY_MAJOR_VERSION];
+       values [MONO_ASSEMBLYREF_MINOR_VERSION] = cols [MONO_ASSEMBLY_MINOR_VERSION];
+       values [MONO_ASSEMBLYREF_BUILD_NUMBER] = cols [MONO_ASSEMBLY_BUILD_NUMBER];
+       values [MONO_ASSEMBLYREF_REV_NUMBER] = cols [MONO_ASSEMBLY_REV_NUMBER];
+       values [MONO_ASSEMBLYREF_FLAGS] = 0;
+       values [MONO_ASSEMBLYREF_CULTURE] = 0;
+       values [MONO_ASSEMBLYREF_HASH_VALUE] = 0;
+
+       if (strcmp ("", image->assembly->aname.culture)) {
+               values [MONO_ASSEMBLYREF_CULTURE] = string_heap_insert (&assembly->sheap,
+                               image->assembly->aname.culture);
+       }
+
+       if ((pubkey = mono_image_get_public_key (image, &publen))) {
+               guchar pubtoken [9];
+               pubtoken [0] = 8;
+               mono_digest_get_public_token (pubtoken + 1, (guchar*)pubkey, publen);
+               values [MONO_ASSEMBLYREF_PUBLIC_KEY] = mono_image_add_stream_data (&assembly->blob, (char*)pubtoken, 9);
+       } else {
+               values [MONO_ASSEMBLYREF_PUBLIC_KEY] = 0;
+       }
+       token <<= MONO_RESOLUTION_SCOPE_BITS;
+       token |= MONO_RESOLUTION_SCOPE_ASSEMBLYREF;
+       g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
+       return token;
+}
+
+#ifndef DISABLE_REFLECTION_EMIT
+gboolean
+mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       mono_error_init (error);
+       memset (rmb, 0, sizeof (ReflectionMethodBuilder));
+
+       rmb->ilgen = mb->ilgen;
+       rmb->rtype = (MonoReflectionType*)mb->rtype;
+       return_val_if_nok (error, FALSE);
+       rmb->parameters = mb->parameters;
+       rmb->generic_params = mb->generic_params;
+       rmb->generic_container = mb->generic_container;
+       rmb->opt_types = NULL;
+       rmb->pinfo = mb->pinfo;
+       rmb->attrs = mb->attrs;
+       rmb->iattrs = mb->iattrs;
+       rmb->call_conv = mb->call_conv;
+       rmb->code = mb->code;
+       rmb->type = mb->type;
+       rmb->name = mb->name;
+       rmb->table_idx = &mb->table_idx;
+       rmb->init_locals = mb->init_locals;
+       rmb->skip_visibility = FALSE;
+       rmb->return_modreq = mb->return_modreq;
+       rmb->return_modopt = mb->return_modopt;
+       rmb->param_modreq = mb->param_modreq;
+       rmb->param_modopt = mb->param_modopt;
+       rmb->permissions = mb->permissions;
+       rmb->mhandle = mb->mhandle;
+       rmb->nrefs = 0;
+       rmb->refs = NULL;
+
+       if (mb->dll) {
+               rmb->charset = mb->charset;
+               rmb->extra_flags = mb->extra_flags;
+               rmb->native_cc = mb->native_cc;
+               rmb->dllentry = mb->dllentry;
+               rmb->dll = mb->dll;
+       }
+
+       return TRUE;
+}
+
+gboolean
+mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       const char *name = mb->attrs & METHOD_ATTRIBUTE_STATIC ? ".cctor": ".ctor";
+
+       mono_error_init (error);
+
+       memset (rmb, 0, sizeof (ReflectionMethodBuilder));
+
+       rmb->ilgen = mb->ilgen;
+       rmb->rtype = mono_type_get_object_checked (mono_domain_get (), &mono_defaults.void_class->byval_arg, error);
+       return_val_if_nok (error, FALSE);
+       rmb->parameters = mb->parameters;
+       rmb->generic_params = NULL;
+       rmb->generic_container = NULL;
+       rmb->opt_types = NULL;
+       rmb->pinfo = mb->pinfo;
+       rmb->attrs = mb->attrs;
+       rmb->iattrs = mb->iattrs;
+       rmb->call_conv = mb->call_conv;
+       rmb->code = NULL;
+       rmb->type = mb->type;
+       rmb->name = mono_string_new (mono_domain_get (), name);
+       rmb->table_idx = &mb->table_idx;
+       rmb->init_locals = mb->init_locals;
+       rmb->skip_visibility = FALSE;
+       rmb->return_modreq = NULL;
+       rmb->return_modopt = NULL;
+       rmb->param_modreq = mb->param_modreq;
+       rmb->param_modopt = mb->param_modopt;
+       rmb->permissions = mb->permissions;
+       rmb->mhandle = mb->mhandle;
+       rmb->nrefs = 0;
+       rmb->refs = NULL;
+
+       return TRUE;
+}
+
+static void
+reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       memset (rmb, 0, sizeof (ReflectionMethodBuilder));
+
+       rmb->ilgen = mb->ilgen;
+       rmb->rtype = mb->rtype;
+       rmb->parameters = mb->parameters;
+       rmb->generic_params = NULL;
+       rmb->generic_container = NULL;
+       rmb->opt_types = NULL;
+       rmb->pinfo = NULL;
+       rmb->attrs = mb->attrs;
+       rmb->iattrs = 0;
+       rmb->call_conv = mb->call_conv;
+       rmb->code = NULL;
+       rmb->type = (MonoObject *) mb->owner;
+       rmb->name = mb->name;
+       rmb->table_idx = NULL;
+       rmb->init_locals = mb->init_locals;
+       rmb->skip_visibility = mb->skip_visibility;
+       rmb->return_modreq = NULL;
+       rmb->return_modopt = NULL;
+       rmb->param_modreq = NULL;
+       rmb->param_modopt = NULL;
+       rmb->permissions = NULL;
+       rmb->mhandle = mb->mhandle;
+       rmb->nrefs = 0;
+       rmb->refs = NULL;
+}      
+#else /* DISABLE_REFLECTION_EMIT */
+gboolean
+mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error) {
+       g_assert_not_reached ();
+       return FALSE;
+}
+gboolean
+mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
+{
+       g_assert_not_reached ();
+       return FALSE;
+}
+#endif /* DISABLE_REFLECTION_EMIT */
+
+#ifndef DISABLE_REFLECTION_EMIT
+static guint32
+mono_image_add_memberef_row (MonoDynamicImage *assembly, guint32 parent, const char *name, guint32 sig)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       MonoDynamicTable *table;
+       guint32 *values;
+       guint32 token, pclass;
+
+       switch (parent & MONO_TYPEDEFORREF_MASK) {
+       case MONO_TYPEDEFORREF_TYPEREF:
+               pclass = MONO_MEMBERREF_PARENT_TYPEREF;
+               break;
+       case MONO_TYPEDEFORREF_TYPESPEC:
+               pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
+               break;
+       case MONO_TYPEDEFORREF_TYPEDEF:
+               pclass = MONO_MEMBERREF_PARENT_TYPEDEF;
+               break;
+       default:
+               g_warning ("unknown typeref or def token 0x%08x for %s", parent, name);
+               return 0;
+       }
+       /* extract the index */
+       parent >>= MONO_TYPEDEFORREF_BITS;
+
+       table = &assembly->tables [MONO_TABLE_MEMBERREF];
+
+       if (assembly->save) {
+               alloc_table (table, table->rows + 1);
+               values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
+               values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
+               values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
+               values [MONO_MEMBERREF_SIGNATURE] = sig;
+       }
+
+       token = MONO_TOKEN_MEMBER_REF | table->next_idx;
+       table->next_idx ++;
+
+       return token;
+}
+
+/*
+ * Insert a memberef row into the metadata: the token that point to the memberref
+ * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
+ * mono_image_get_fieldref_token()).
+ * The sig param is an index to an already built signature.
+ */
+static guint32
+mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, const char *name, guint32 sig)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       guint32 parent = mono_image_typedef_or_ref (assembly, type);
+       return mono_image_add_memberef_row (assembly, parent, name, sig);
+}
+
+
+static guint32
+mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
+{
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       guint32 token;
+       MonoMethodSignature *sig;
+       
+       create_typespec = create_typespec && method->is_generic && method->klass->image != &assembly->image;
+
+       if (create_typespec) {
+               token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1)));
+               if (token)
+                       return token;
+       } 
+
+       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
+       if (token && !create_typespec)
+               return token;
+
+       g_assert (!method->is_inflated);
+       if (!token) {
+               /*
+                * A methodref signature can't contain an unmanaged calling convention.
+                */
+               sig = mono_metadata_signature_dup (mono_method_signature (method));
+               if ((sig->call_convention != MONO_CALL_DEFAULT) && (sig->call_convention != MONO_CALL_VARARG))
+                       sig->call_convention = MONO_CALL_DEFAULT;
+               token = mono_image_get_memberref_token (assembly, &method->klass->byval_arg,
+                       method->name,  mono_dynimage_encode_method_signature (assembly, sig));
+               g_free (sig);
+               g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
+       }
+
+       if (create_typespec) {
+               MonoDynamicTable *table = &assembly->tables [MONO_TABLE_METHODSPEC];
+               g_assert (mono_metadata_token_table (token) == MONO_TABLE_MEMBERREF);
+               token = (mono_metadata_token_index (token) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
+
+               if (assembly->save) {
+                       guint32 *values;
+
+                       alloc_table (table, table->rows + 1);
+                       values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
+                       values [MONO_METHODSPEC_METHOD] = token;
+                       values [MONO_METHODSPEC_SIGNATURE] = mono_dynimage_encode_generic_method_sig (assembly, &mono_method_get_generic_container (method)->context);
+               }
+
+               token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
+               table->next_idx ++;
+               /*methodspec and memberef tokens are diferent, */
+               g_hash_table_insert (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1), GUINT_TO_POINTER (token));
+               return token;
+       }
+       return token;
+}
+
+static guint32
+mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method, MonoError *error)
+{
+       guint32 token, parent, sig;
+       ReflectionMethodBuilder rmb;
+       MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)method->type;
+       
+       mono_error_init (error);
+       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
+       if (token)
+               return token;
+
+       if (!mono_reflection_methodbuilder_from_method_builder (&rmb, method, error))
+               return 0;
+
+       /*
+        * A methodref signature can't contain an unmanaged calling convention.
+        * Since some flags are encoded as part of call_conv, we need to check against it.
+       */
+       if ((rmb.call_conv & ~0x60) != MONO_CALL_DEFAULT && (rmb.call_conv & ~0x60) != MONO_CALL_VARARG)
+               rmb.call_conv = (rmb.call_conv & 0x60) | MONO_CALL_DEFAULT;
+
+       sig = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
+       return_val_if_nok (error, 0);
+
+       if (tb->generic_params) {
+               parent = mono_dynimage_encode_generic_typespec (assembly, tb, error);
+               return_val_if_nok (error, 0);
+       } else {
+               MonoType *t = mono_reflection_type_get_handle ((MonoReflectionType*)rmb.type, error);
+               return_val_if_nok (error, 0);
+
+               parent = mono_image_typedef_or_ref (assembly, t);
+       }
+
+       char *name = mono_string_to_utf8_checked (method->name, error);
+       return_val_if_nok (error, 0);
+
+       token = mono_image_add_memberef_row (assembly, parent, name, sig);
+       g_free (name);
+
+       g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
+
+       return token;
+}
+
+static guint32
+mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 original,
+                                    const gchar *name, guint32 sig)
+{
+       MonoDynamicTable *table;
+       guint32 token;
+       guint32 *values;
+       
+       table = &assembly->tables [MONO_TABLE_MEMBERREF];
+
+       if (assembly->save) {
+               alloc_table (table, table->rows + 1);
+               values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
+               values [MONO_MEMBERREF_CLASS] = original;
+               values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
+               values [MONO_MEMBERREF_SIGNATURE] = sig;
+       }
+
+       token = MONO_TOKEN_MEMBER_REF | table->next_idx;
+       table->next_idx ++;
+
+       return token;
+}
+
+static guint32
+mono_image_get_methodspec_token_for_generic_method_definition (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, MonoError *error)
+{
+       MonoDynamicTable *table;
+       guint32 *values;
+       guint32 token, mtoken = 0;
+
+       mono_error_init (error);
+       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->methodspec, mb));
+       if (token)
+               return token;
+
+       table = &assembly->tables [MONO_TABLE_METHODSPEC];
+
+       mtoken = mono_image_get_methodref_token_for_methodbuilder (assembly, mb, error);
+       if (!mono_error_ok (error))
+               return 0;
+
+       switch (mono_metadata_token_table (mtoken)) {
+       case MONO_TABLE_MEMBERREF:
+               mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
+               break;
+       case MONO_TABLE_METHOD:
+               mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
+               break;
+       default:
+               g_assert_not_reached ();
+       }
+
+       if (assembly->save) {
+               alloc_table (table, table->rows + 1);
+               values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
+               values [MONO_METHODSPEC_METHOD] = mtoken;
+               values [MONO_METHODSPEC_SIGNATURE] = mono_dynimage_encode_generic_method_definition_sig (assembly, mb);
+       }
+
+       token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
+       table->next_idx ++;
+
+       mono_g_hash_table_insert (assembly->methodspec, mb, GUINT_TO_POINTER(token));
+       return token;
+}
+
+static guint32
+mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_methodspec, MonoError *error)
+{
+       guint32 token;
+
+       mono_error_init (error);
+
+       if (mb->generic_params && create_methodspec) 
+               return mono_image_get_methodspec_token_for_generic_method_definition (assembly, mb, error);
+
+       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, mb));
+       if (token)
+               return token;
+
+       token = mono_image_get_methodref_token_for_methodbuilder (assembly, mb, error);
+       if (!mono_error_ok (error))
+               return 0;
+       mono_g_hash_table_insert (assembly->handleref_managed, mb, GUINT_TO_POINTER(token));
+       return token;
+}
+
+static guint32
+mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtorBuilder *mb, MonoError *error)
+{
+       guint32 token, parent, sig;
+       ReflectionMethodBuilder rmb;
+       char *name;
+       MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mb->type;
+       
+       mono_error_init (error);
+       
+       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, mb));
+       if (token)
+               return token;
+
+       if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
+               return 0;
+
+       if (tb->generic_params) {
+               parent = mono_dynimage_encode_generic_typespec (assembly, tb, error);
+               return_val_if_nok (error, 0);
+       } else {
+               MonoType * type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
+               return_val_if_nok (error, 0);
+               parent = mono_image_typedef_or_ref (assembly, type);
+       }
+       
+       name = mono_string_to_utf8_checked (rmb.name, error);
+       return_val_if_nok (error, 0);
+       sig = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
+       return_val_if_nok (error, 0);
+
+       token = mono_image_add_memberef_row (assembly, parent, name, sig);
+
+       g_free (name);
+       mono_g_hash_table_insert (assembly->handleref_managed, mb, GUINT_TO_POINTER(token));
+       return token;
+}
+#endif
+
+static gboolean
+is_field_on_inst (MonoClassField *field)
+{
+       return field->parent->generic_class && field->parent->generic_class->is_dynamic;
+}
+
+#ifndef DISABLE_REFLECTION_EMIT
+static guint32
+mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObject *f, MonoClassField *field)
+{
+       MonoType *type;
+       guint32 token;
+
+       g_assert (field);
+       g_assert (field->parent);
+
+       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
+       if (token)
+               return token;
+
+       if (field->parent->generic_class && field->parent->generic_class->container_class && field->parent->generic_class->container_class->fields) {
+               int index = field - field->parent->fields;
+               type = mono_field_get_type (&field->parent->generic_class->container_class->fields [index]);
+       } else {
+               type = mono_field_get_type (field);
+       }
+       token = mono_image_get_memberref_token (assembly, &field->parent->byval_arg,
+                                                                                       mono_field_get_name (field),
+                                                                                       mono_dynimage_encode_fieldref_signature (assembly, field->parent->image, type));
+       mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER(token));
+       return token;
+}
+
+static guint32
+mono_image_get_field_on_inst_token (MonoDynamicImage *assembly, MonoReflectionFieldOnTypeBuilderInst *f, MonoError *error)
+{
+       guint32 token;
+       MonoClass *klass;
+       MonoGenericClass *gclass;
+       MonoType *type;
+       char *name;
+
+       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
+       if (token)
+               return token;
+       if (is_sre_field_builder (mono_object_class (f->fb))) {
+               MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)f->fb;
+               type = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst, error);
+               return_val_if_nok (error, 0);
+               klass = mono_class_from_mono_type (type);
+               gclass = type->data.generic_class;
+               g_assert (gclass->is_dynamic);
+
+               guint32 sig_token = mono_dynimage_encode_field_signature (assembly, fb, error);
+               return_val_if_nok (error, 0);
+               name = mono_string_to_utf8_checked (fb->name, error);
+               return_val_if_nok (error, 0);
+               token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig_token);
+               g_free (name);          
+       } else if (is_sr_mono_field (mono_object_class (f->fb))) {
+               guint32 sig;
+               MonoClassField *field = ((MonoReflectionField *)f->fb)->field;
+
+               type = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst, error);
+               return_val_if_nok (error, 0);
+               klass = mono_class_from_mono_type (type);
+
+               sig = mono_dynimage_encode_fieldref_signature (assembly, field->parent->image, field->type);
+               token = mono_image_get_memberref_token (assembly, &klass->byval_arg, field->name, sig);
+       } else {
+               char *name = mono_type_get_full_name (mono_object_class (f->fb));
+               g_error ("mono_image_get_field_on_inst_token: don't know how to handle %s", name);
+       }
+
+       mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER (token));
+       return token;
+}
+
+static guint32
+mono_image_get_ctor_on_inst_token (MonoDynamicImage *assembly, MonoReflectionCtorOnTypeBuilderInst *c, gboolean create_methodspec, MonoError *error)
+{
+       guint32 sig, token;
+       MonoClass *klass;
+       MonoGenericClass *gclass;
+       MonoType *type;
+
+       mono_error_init (error);
+
+       /* A ctor cannot be a generic method, so we can ignore create_methodspec */
+
+       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, c));
+       if (token)
+               return token;
+
+       if (mono_is_sre_ctor_builder (mono_object_class (c->cb))) {
+               MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder *)c->cb;
+               ReflectionMethodBuilder rmb;
+               char *name;
+
+               type = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst, error);
+               return_val_if_nok (error, 0);
+               klass = mono_class_from_mono_type (type);
+
+               gclass = type->data.generic_class;
+               g_assert (gclass->is_dynamic);
+
+               if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, cb, error))
+                       return 0;
+
+               sig = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
+               return_val_if_nok (error, 0);
+
+               name = mono_string_to_utf8_checked (rmb.name, error);
+               return_val_if_nok (error, 0);
+
+               token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
+               g_free (name);
+       } else if (mono_is_sr_mono_cmethod (mono_object_class (c->cb))) {
+               MonoMethod *mm = ((MonoReflectionMethod *)c->cb)->method;
+
+               type = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst, error);
+               return_val_if_nok (error, 0);
+               klass = mono_class_from_mono_type (type);
+
+               sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (mm));
+               token = mono_image_get_memberref_token (assembly, &klass->byval_arg, mm->name, sig);
+       } else {
+               char *name = mono_type_get_full_name (mono_object_class (c->cb));
+               g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
+       }
+
+
+       mono_g_hash_table_insert (assembly->handleref_managed, c, GUINT_TO_POINTER (token));
+       return token;
+}
+
+MonoMethod*
+mono_reflection_method_on_tb_inst_get_handle (MonoReflectionMethodOnTypeBuilderInst *m, MonoError *error)
+{
+       MonoClass *klass;
+       MonoGenericContext tmp_context;
+       MonoType **type_argv;
+       MonoGenericInst *ginst;
+       MonoMethod *method, *inflated;
+       int count, i;
+
+       mono_error_init (error);
+
+       mono_reflection_init_type_builder_generics ((MonoObject*)m->inst, error);
+       return_val_if_nok (error, NULL);
+
+       method = inflate_method (m->inst, (MonoObject*)m->mb, error);
+       return_val_if_nok (error, NULL);
+
+       klass = method->klass;
+
+       if (m->method_args == NULL)
+               return method;
+
+       if (method->is_inflated)
+               method = ((MonoMethodInflated *) method)->declaring;
+
+       count = mono_array_length (m->method_args);
+
+       type_argv = g_new0 (MonoType *, count);
+       for (i = 0; i < count; i++) {
+               MonoReflectionType *garg = (MonoReflectionType *)mono_array_get (m->method_args, gpointer, i);
+               type_argv [i] = mono_reflection_type_get_handle (garg, error);
+               return_val_if_nok (error, NULL);
+       }
+       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.method_inst = ginst;
+
+       inflated = mono_class_inflate_generic_method_checked (method, &tmp_context, error);
+       mono_error_assert_ok (error);
+       return inflated;
+}
+
+static guint32
+mono_image_get_method_on_inst_token (MonoDynamicImage *assembly, MonoReflectionMethodOnTypeBuilderInst *m, gboolean create_methodspec, MonoError *error)
+{
+       guint32 sig, token = 0;
+       MonoType *type;
+       MonoClass *klass;
+
+       mono_error_init (error);
+
+       if (m->method_args) {
+               MonoMethod *inflated;
+
+               inflated = mono_reflection_method_on_tb_inst_get_handle (m, error);
+               return_val_if_nok (error, 0);
+
+               if (create_methodspec)
+                       token = mono_image_get_methodspec_token (assembly, inflated);
+               else
+                       token = mono_image_get_inflated_method_token (assembly, inflated);
+               return token;
+       }
+
+       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, m));
+       if (token)
+               return token;
+
+       if (is_sre_method_builder (mono_object_class (m->mb))) {
+               MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)m->mb;
+               MonoGenericClass *gclass;
+               ReflectionMethodBuilder rmb;
+               char *name;
+
+               type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
+               return_val_if_nok (error, 0);
+               klass = mono_class_from_mono_type (type);
+               gclass = type->data.generic_class;
+               g_assert (gclass->is_dynamic);
+
+               if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
+                       return 0;
+
+               sig = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
+               return_val_if_nok (error, 0);
+
+               name = mono_string_to_utf8_checked (rmb.name, error);
+               return_val_if_nok (error, 0);
+
+               token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
+               g_free (name);          
+       } else if (is_sr_mono_method (mono_object_class (m->mb))) {
+               MonoMethod *mm = ((MonoReflectionMethod *)m->mb)->method;
+
+               type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
+               return_val_if_nok (error, 0);
+               klass = mono_class_from_mono_type (type);
+
+               sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (mm));
+               token = mono_image_get_memberref_token (assembly, &klass->byval_arg, mm->name, sig);
+       } else {
+               char *name = mono_type_get_full_name (mono_object_class (m->mb));
+               g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
+       }
+
+       mono_g_hash_table_insert (assembly->handleref_managed, m, GUINT_TO_POINTER (token));
+       return token;
+}
+
+static guint32
+method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
+{
+       MonoDynamicTable *table;
+       guint32 *values;
+       guint32 token, mtoken = 0, sig;
+       MonoMethodInflated *imethod;
+       MonoMethod *declaring;
+
+       table = &assembly->tables [MONO_TABLE_METHODSPEC];
+
+       g_assert (method->is_inflated);
+       imethod = (MonoMethodInflated *) method;
+       declaring = imethod->declaring;
+
+       sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (declaring));
+       mtoken = mono_image_get_memberref_token (assembly, &method->klass->byval_arg, declaring->name, sig);
+
+       if (!mono_method_signature (declaring)->generic_param_count)
+               return mtoken;
+
+       switch (mono_metadata_token_table (mtoken)) {
+       case MONO_TABLE_MEMBERREF:
+               mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
+               break;
+       case MONO_TABLE_METHOD:
+               mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
+               break;
+       default:
+               g_assert_not_reached ();
+       }
+
+       sig = mono_dynimage_encode_generic_method_sig (assembly, mono_method_get_context (method));
+
+       if (assembly->save) {
+               alloc_table (table, table->rows + 1);
+               values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
+               values [MONO_METHODSPEC_METHOD] = mtoken;
+               values [MONO_METHODSPEC_SIGNATURE] = sig;
+       }
+
+       token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
+       table->next_idx ++;
+
+       return token;
+}
+
+static guint32
+mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method)
+{
+       MonoMethodInflated *imethod;
+       guint32 token;
+       
+       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
+       if (token)
+               return token;
+
+       g_assert (method->is_inflated);
+       imethod = (MonoMethodInflated *) method;
+
+       if (mono_method_signature (imethod->declaring)->generic_param_count) {
+               token = method_encode_methodspec (assembly, method);
+       } else {
+               guint32 sig = mono_dynimage_encode_method_signature (
+                       assembly, mono_method_signature (imethod->declaring));
+               token = mono_image_get_memberref_token (
+                       assembly, &method->klass->byval_arg, method->name, sig);
+       }
+
+       g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
+       return token;
+}
+
+static guint32
+mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m)
+{
+       MonoMethodInflated *imethod = (MonoMethodInflated *) m;
+       guint32 sig, token;
+
+       sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (imethod->declaring));
+       token = mono_image_get_memberref_token (
+               assembly, &m->klass->byval_arg, m->name, sig);
+
+       return token;
+}
+
+/*
+ * Return a copy of TYPE, adding the custom modifiers in MODREQ and MODOPT.
+ */
+static MonoType*
+add_custom_modifiers (MonoDynamicImage *assembly, MonoType *type, MonoArray *modreq, MonoArray *modopt, MonoError *error)
+{
+       int i, count, len, pos;
+       MonoType *t;
+
+       mono_error_init (error);
+
+       count = 0;
+       if (modreq)
+               count += mono_array_length (modreq);
+       if (modopt)
+               count += mono_array_length (modopt);
+
+       if (count == 0)
+               return mono_metadata_type_dup (NULL, type);
+
+       len = MONO_SIZEOF_TYPE + ((gint32)count) * sizeof (MonoCustomMod);
+       t = (MonoType *)g_malloc (len);
+       memcpy (t, type, MONO_SIZEOF_TYPE);
+
+       t->num_mods = count;
+       pos = 0;
+       if (modreq) {
+               for (i = 0; i < mono_array_length (modreq); ++i) {
+                       MonoType *mod = mono_type_array_get_and_resolve (modreq, i, error);
+                       if (!is_ok (error))
+                               goto fail;
+                       t->modifiers [pos].required = 1;
+                       t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod);
+                       pos ++;
+               }
+       }
+       if (modopt) {
+               for (i = 0; i < mono_array_length (modopt); ++i) {
+                       MonoType *mod = mono_type_array_get_and_resolve (modopt, i, error);
+                       if (!is_ok (error))
+                               goto fail;
+                       t->modifiers [pos].required = 0;
+                       t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod);
+                       pos ++;
+               }
+       }
+
+       return t;
+fail:
+       g_free (t);
+       return NULL;
+}
+
+void
+mono_reflection_init_type_builder_generics (MonoObject *type, MonoError *error)
+{
+       MonoReflectionTypeBuilder *tb;
+
+       mono_error_init (error);
+
+       if (!is_sre_type_builder(mono_object_class (type)))
+               return;
+       tb = (MonoReflectionTypeBuilder *)type;
+
+       if (tb && tb->generic_container)
+               mono_reflection_create_generic_class (tb, error);
+}
+
+static guint32
+mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb, MonoError *error)
+{
+       MonoDynamicTable *table;
+       MonoType *custom = NULL, *type;
+       guint32 *values;
+       guint32 token, pclass, parent, sig;
+       gchar *name;
+
+       mono_error_init (error);
+
+       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, fb));
+       if (token)
+               return token;
+
+       MonoType *typeb = mono_reflection_type_get_handle (fb->typeb, error);
+       return_val_if_nok (error, 0);
+       /* FIXME: is this call necessary? */
+       mono_class_from_mono_type (typeb);
+
+       /*FIXME this is one more layer of ugliness due how types are created.*/
+       mono_reflection_init_type_builder_generics (fb->type, error);
+       return_val_if_nok (error, 0);
+
+       /* fb->type does not include the custom modifiers */
+       /* FIXME: We should do this in one place when a fieldbuilder is created */
+       type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
+       return_val_if_nok (error, 0);
+
+       if (fb->modreq || fb->modopt) {
+               type = custom = add_custom_modifiers (assembly, type, fb->modreq, fb->modopt, error);
+               return_val_if_nok (error, 0);
+       }
+
+       sig = mono_dynimage_encode_fieldref_signature (assembly, NULL, type);
+       g_free (custom);
+
+       parent = mono_dynimage_encode_generic_typespec (assembly, (MonoReflectionTypeBuilder *) fb->typeb, error);
+       return_val_if_nok (error, 0);
+       g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_TYPEDEFORREF_TYPESPEC);
+       
+       pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
+       parent >>= MONO_TYPEDEFORREF_BITS;
+
+       table = &assembly->tables [MONO_TABLE_MEMBERREF];
+
+       name = mono_string_to_utf8_checked (fb->name, error);
+       return_val_if_nok (error, 0);
+
+       if (assembly->save) {
+               alloc_table (table, table->rows + 1);
+               values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
+               values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
+               values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
+               values [MONO_MEMBERREF_SIGNATURE] = sig;
+       }
+
+       token = MONO_TOKEN_MEMBER_REF | table->next_idx;
+       table->next_idx ++;
+       mono_g_hash_table_insert (assembly->handleref_managed, fb, GUINT_TO_POINTER(token));
+       g_free (name);
+       return token;
+}
+
+static guint32 
+mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error)
+{
+       guint32 idx;
+       MonoDynamicTable *table;
+       guint32 *values;
+
+       mono_error_init (error);
+
+       table = &assembly->tables [MONO_TABLE_STANDALONESIG];
+       idx = table->next_idx ++;
+       table->rows ++;
+       alloc_table (table, table->rows);
+       values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
+
+       values [MONO_STAND_ALONE_SIGNATURE] =
+               mono_dynimage_encode_reflection_sighelper (assembly, helper, error);
+       return_val_if_nok (error, 0);
+       
+       return idx;
+}
+
+static int
+reflection_cc_to_file (int call_conv) {
+       switch (call_conv & 0x3) {
+       case 0:
+       case 1: return MONO_CALL_DEFAULT;
+       case 2: return MONO_CALL_VARARG;
+       default:
+               g_assert_not_reached ();
+       }
+       return 0;
+}
+#endif /* !DISABLE_REFLECTION_EMIT */
+
+struct _ArrayMethod {
+       MonoType *parent;
+       MonoMethodSignature *sig;
+       char *name;
+       guint32 token;
+};
+
+void
+mono_sre_array_method_free (ArrayMethod *am)
+{
+       g_free (am->sig);
+       g_free (am->name);
+       g_free (am);
+}
+
+#ifndef DISABLE_REFLECTION_EMIT
+static guint32
+mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMethod *m, MonoError *error)
+{
+       guint32 nparams, i;
+       GList *tmp;
+       char *name = NULL;
+       MonoMethodSignature *sig;
+       ArrayMethod *am = NULL;
+       MonoType *mtype;
+
+       mono_error_init (error);
+
+       nparams = mono_array_length (m->parameters);
+       sig = (MonoMethodSignature *)g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * nparams);
+       sig->hasthis = 1;
+       sig->sentinelpos = -1;
+       sig->call_convention = reflection_cc_to_file (m->call_conv);
+       sig->param_count = nparams;
+       if (m->ret) {
+               sig->ret = mono_reflection_type_get_handle (m->ret, error);
+               if (!is_ok (error))
+                       goto fail;
+       } else
+               sig->ret = &mono_defaults.void_class->byval_arg;
+
+       mtype = mono_reflection_type_get_handle (m->parent, error);
+       if (!is_ok (error))
+               goto fail;
+
+       for (i = 0; i < nparams; ++i) {
+               sig->params [i] = mono_type_array_get_and_resolve (m->parameters, i, error);
+               if (!is_ok (error))
+                       goto fail;
+       }
+
+       name = mono_string_to_utf8_checked (m->name, error);
+       if (!is_ok (error))
+               goto fail;
+       for (tmp = assembly->array_methods; tmp; tmp = tmp->next) {
+               am = (ArrayMethod *)tmp->data;
+               if (strcmp (name, am->name) == 0 && 
+                               mono_metadata_type_equal (am->parent, mtype) &&
+                               mono_metadata_signature_equal (am->sig, sig)) {
+                       g_free (name);
+                       g_free (sig);
+                       m->table_idx = am->token & 0xffffff;
+                       return am->token;
+               }
+       }
+       am = g_new0 (ArrayMethod, 1);
+       am->name = name;
+       am->sig = sig;
+       am->parent = mtype;
+       am->token = mono_image_get_memberref_token (assembly, am->parent, name,
+               mono_dynimage_encode_method_signature (assembly, sig));
+       assembly->array_methods = g_list_prepend (assembly->array_methods, am);
+       m->table_idx = am->token & 0xffffff;
+       return am->token;
+fail:
+       g_free (am);
+       g_free (name);
+       g_free (sig);
+       return 0;
+
+}
+#endif
+
+#ifndef DISABLE_REFLECTION_EMIT
+
+/*
+ * mono_image_insert_string:
+ * @module: module builder object
+ * @str: a string
+ *
+ * Insert @str into the user string stream of @module.
+ */
+guint32
+mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
+{
+       MonoDynamicImage *assembly;
+       guint32 idx;
+       char buf [16];
+       char *b = buf;
+       
+       if (!module->dynamic_image)
+               mono_image_module_basic_init (module);
+
+       assembly = module->dynamic_image;
+       
+       if (assembly->save) {
+               mono_metadata_encode_value (1 | (str->length * 2), b, &b);
+               idx = mono_image_add_stream_data (&assembly->us, buf, b-buf);
+#if G_BYTE_ORDER != G_LITTLE_ENDIAN
+       {
+               char *swapped = g_malloc (2 * mono_string_length (str));
+               const char *p = (const char*)mono_string_chars (str);
+
+               swap_with_size (swapped, p, 2, mono_string_length (str));
+               mono_image_add_stream_data (&assembly->us, swapped, str->length * 2);
+               g_free (swapped);
+       }
+#else
+               mono_image_add_stream_data (&assembly->us, (const char*)mono_string_chars (str), str->length * 2);
+#endif
+               mono_image_add_stream_data (&assembly->us, "", 1);
+       } else {
+               idx = assembly->us.index ++;
+       }
+
+       mono_dynamic_image_register_token (assembly, MONO_TOKEN_STRING | idx, (MonoObject*)str);
+
+       return MONO_TOKEN_STRING | idx;
+}
+
+guint32
+mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types, MonoError *error)
+{
+       MonoClass *klass;
+       guint32 token = 0;
+       MonoMethodSignature *sig;
+
+       mono_error_init (error);
+
+       klass = obj->vtable->klass;
+       if (strcmp (klass->name, "MonoMethod") == 0 || strcmp (klass->name, "MonoCMethod") == 0) {
+               MonoMethod *method = ((MonoReflectionMethod *)obj)->method;
+               MonoMethodSignature *old;
+               guint32 sig_token, parent;
+               int nargs, i;
+
+               g_assert (opt_param_types && (mono_method_signature (method)->sentinelpos >= 0));
+
+               nargs = mono_array_length (opt_param_types);
+               old = mono_method_signature (method);
+               sig = mono_metadata_signature_alloc ( &assembly->image, old->param_count + nargs);
+
+               sig->hasthis = old->hasthis;
+               sig->explicit_this = old->explicit_this;
+               sig->call_convention = old->call_convention;
+               sig->generic_param_count = old->generic_param_count;
+               sig->param_count = old->param_count + nargs;
+               sig->sentinelpos = old->param_count;
+               sig->ret = old->ret;
+
+               for (i = 0; i < old->param_count; i++)
+                       sig->params [i] = old->params [i];
+
+               for (i = 0; i < nargs; i++) {
+                       MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
+                       sig->params [old->param_count + i] = mono_reflection_type_get_handle (rt, error);
+                       if (!is_ok (error)) goto fail;
+               }
+
+               parent = mono_image_typedef_or_ref (assembly, &method->klass->byval_arg);
+               g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_MEMBERREF_PARENT_TYPEREF);
+               parent >>= MONO_TYPEDEFORREF_BITS;
+
+               parent <<= MONO_MEMBERREF_PARENT_BITS;
+               parent |= MONO_MEMBERREF_PARENT_TYPEREF;
+
+               sig_token = mono_dynimage_encode_method_signature (assembly, sig);
+               token = mono_image_get_varargs_method_token (assembly, parent, method->name, sig_token);
+       } else if (strcmp (klass->name, "MethodBuilder") == 0) {
+               MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
+               ReflectionMethodBuilder rmb;
+               guint32 parent, sig_token;
+               int nopt_args, nparams, ngparams, i;
+
+               if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
+                       goto fail;
+               
+               rmb.opt_types = opt_param_types;
+               nopt_args = mono_array_length (opt_param_types);
+
+               nparams = rmb.parameters ? mono_array_length (rmb.parameters): 0;
+               ngparams = rmb.generic_params ? mono_array_length (rmb.generic_params): 0;
+               sig = mono_metadata_signature_alloc (&assembly->image, nparams + nopt_args);
+
+               sig->hasthis = !(rmb.attrs & METHOD_ATTRIBUTE_STATIC);
+               sig->explicit_this = (rmb.call_conv & 0x40) == 0x40;
+               sig->call_convention = rmb.call_conv;
+               sig->generic_param_count = ngparams;
+               sig->param_count = nparams + nopt_args;
+               sig->sentinelpos = nparams;
+               sig->ret = mono_reflection_type_get_handle (rmb.rtype, error);
+               if (!is_ok (error)) goto fail;
+
+               for (i = 0; i < nparams; i++) {
+                       MonoReflectionType *rt = mono_array_get (rmb.parameters, MonoReflectionType *, i);
+                       sig->params [i] = mono_reflection_type_get_handle (rt, error);
+                       if (!is_ok (error)) goto fail;
+               }
+
+               for (i = 0; i < nopt_args; i++) {
+                       MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
+                       sig->params [nparams + i] = mono_reflection_type_get_handle (rt, error);
+                       if (!is_ok (error)) goto fail;
+               }
+
+               sig_token = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
+               if (!is_ok (error))
+                       goto fail;
+
+               parent = mono_image_create_token (assembly, obj, TRUE, TRUE, error);
+               if (!mono_error_ok (error))
+                       goto fail;
+               g_assert (mono_metadata_token_table (parent) == MONO_TABLE_METHOD);
+
+               parent = mono_metadata_token_index (parent) << MONO_MEMBERREF_PARENT_BITS;
+               parent |= MONO_MEMBERREF_PARENT_METHODDEF;
+
+               char *name = mono_string_to_utf8_checked (rmb.name, error);
+               if (!is_ok (error)) goto fail;
+               token = mono_image_get_varargs_method_token (
+                       assembly, parent, name, sig_token);
+               g_free (name);
+       } else {
+               g_error ("requested method token for %s\n", klass->name);
+       }
+
+       g_hash_table_insert (assembly->vararg_aux_hash, GUINT_TO_POINTER (token), sig);
+       mono_dynamic_image_register_token (assembly, token, obj);
+       return token;
+fail:
+       g_assert (!mono_error_ok (error));
+       return 0;
+}
+
+/*
+ * mono_image_create_token:
+ * @assembly: a dynamic assembly
+ * @obj:
+ * @register_token: Whenever to register the token in the assembly->tokens hash. 
+ *
+ * Get a token to insert in the IL code stream for the given MemberInfo.
+ * The metadata emission routines need to pass FALSE as REGISTER_TOKEN, since by that time, 
+ * the table_idx-es were recomputed, so registering the token would overwrite an existing 
+ * entry.
+ */
+guint32
+mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, 
+                        gboolean create_open_instance, gboolean register_token,
+                        MonoError *error)
+{
+       MonoClass *klass;
+       guint32 token = 0;
+
+       mono_error_init (error);
+
+       klass = obj->vtable->klass;
+
+       /* Check for user defined reflection objects */
+       /* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
+       if (klass->image != mono_defaults.corlib || (strcmp (klass->name, "TypeDelegator") == 0)) {
+               mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported");
+               return 0;
+       }
+
+       if (strcmp (klass->name, "MethodBuilder") == 0) {
+               MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
+               MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
+
+               if (tb->module->dynamic_image == assembly && !tb->generic_params && !mb->generic_params)
+                       token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
+               else {
+                       token = mono_image_get_methodbuilder_token (assembly, mb, create_open_instance, error);
+                       if (!mono_error_ok (error))
+                               return 0;
+               }
+               /*g_print ("got token 0x%08x for %s\n", token, mono_string_to_utf8 (mb->name));*/
+       } else if (strcmp (klass->name, "ConstructorBuilder") == 0) {
+               MonoReflectionCtorBuilder *mb = (MonoReflectionCtorBuilder *)obj;
+               MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
+
+               if (tb->module->dynamic_image == assembly && !tb->generic_params)
+                       token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
+               else {
+                       token = mono_image_get_ctorbuilder_token (assembly, mb, error);
+                       if (!mono_error_ok (error))
+                               return 0;
+               }
+               /*g_print ("got token 0x%08x for %s\n", token, mono_string_to_utf8 (mb->name));*/
+       } else if (strcmp (klass->name, "FieldBuilder") == 0) {
+               MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)obj;
+               MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)fb->typeb;
+               if (tb->generic_params) {
+                       token = mono_image_get_generic_field_token (assembly, fb, error);
+                       return_val_if_nok (error, 0);
+               } else {
+                       if (tb->module->dynamic_image == assembly) {
+                               token = fb->table_idx | MONO_TOKEN_FIELD_DEF;
+                       } else {
+                               token = mono_image_get_fieldref_token (assembly, (MonoObject*)fb, fb->handle);
+                       }
+               }
+       } else if (strcmp (klass->name, "TypeBuilder") == 0) {
+               MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)obj;
+               if (create_open_instance && tb->generic_params) {
+                       MonoType *type;
+                       mono_reflection_init_type_builder_generics (obj, error);
+                       return_val_if_nok (error, 0);
+                       type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
+                       return_val_if_nok (error, 0);
+                       token = mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
+                       token = mono_metadata_token_from_dor (token);
+               } else if (tb->module->dynamic_image == assembly) {
+                       token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
+               } else {
+                       MonoType *type;
+                       type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
+                       return_val_if_nok (error, 0);
+                       token = mono_metadata_token_from_dor (mono_image_typedef_or_ref (assembly, type));
+               }
+       } else if (strcmp (klass->name, "RuntimeType") == 0) {
+               MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
+               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));
+       } else if (strcmp (klass->name, "GenericTypeParameterBuilder") == 0) {
+               MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
+               return_val_if_nok (error, 0);
+               token = mono_metadata_token_from_dor (
+                       mono_image_typedef_or_ref (assembly, type));
+       } else if (strcmp (klass->name, "MonoGenericClass") == 0) {
+               MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
+               return_val_if_nok (error, 0);
+               token = mono_metadata_token_from_dor (
+                       mono_image_typedef_or_ref (assembly, type));
+       } else if (strcmp (klass->name, "MonoCMethod") == 0 ||
+                  strcmp (klass->name, "MonoMethod") == 0 ||
+                  strcmp (klass->name, "MonoGenericMethod") == 0 ||
+                  strcmp (klass->name, "MonoGenericCMethod") == 0) {
+               MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
+               if (m->method->is_inflated) {
+                       if (create_open_instance)
+                               token = mono_image_get_methodspec_token (assembly, m->method);
+                       else
+                               token = mono_image_get_inflated_method_token (assembly, m->method);
+               } else if ((m->method->klass->image == &assembly->image) &&
+                        !m->method->klass->generic_class) {
+                       static guint32 method_table_idx = 0xffffff;
+                       if (m->method->klass->wastypebuilder) {
+                               /* we use the same token as the one that was assigned
+                                * to the Methodbuilder.
+                                * FIXME: do the equivalent for Fields.
+                                */
+                               token = m->method->token;
+                       } else {
+                               /*
+                                * Each token should have a unique index, but the indexes are
+                                * assigned by managed code, so we don't know about them. An
+                                * easy solution is to count backwards...
+                                */
+                               method_table_idx --;
+                               token = MONO_TOKEN_METHOD_DEF | method_table_idx;
+                       }
+               } else {
+                       token = mono_image_get_methodref_token (assembly, m->method, create_open_instance);
+               }
+               /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
+       } else if (strcmp (klass->name, "MonoField") == 0) {
+               MonoReflectionField *f = (MonoReflectionField *)obj;
+               if ((f->field->parent->image == &assembly->image) && !is_field_on_inst (f->field)) {
+                       static guint32 field_table_idx = 0xffffff;
+                       field_table_idx --;
+                       token = MONO_TOKEN_FIELD_DEF | field_table_idx;
+               } else {
+                       token = mono_image_get_fieldref_token (assembly, (MonoObject*)f, f->field);
+               }
+               /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
+       } else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
+               MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod *)obj;
+               token = mono_image_get_array_token (assembly, m, error);
+               return_val_if_nok (error, 0);
+       } else if (strcmp (klass->name, "SignatureHelper") == 0) {
+               MonoReflectionSigHelper *s = (MonoReflectionSigHelper*)obj;
+               token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s, error);
+               return_val_if_nok (error, 0);
+       } else if (strcmp (klass->name, "EnumBuilder") == 0) {
+               MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
+               return_val_if_nok (error, 0);
+               token = mono_metadata_token_from_dor (
+                       mono_image_typedef_or_ref (assembly, type));
+       } else if (strcmp (klass->name, "FieldOnTypeBuilderInst") == 0) {
+               MonoReflectionFieldOnTypeBuilderInst *f = (MonoReflectionFieldOnTypeBuilderInst*)obj;
+               token = mono_image_get_field_on_inst_token (assembly, f, error);
+               return_val_if_nok (error, 0);
+       } else if (strcmp (klass->name, "ConstructorOnTypeBuilderInst") == 0) {
+               MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj;
+               token = mono_image_get_ctor_on_inst_token (assembly, c, create_open_instance, error);
+               if (!mono_error_ok (error))
+                       return 0;
+       } else if (strcmp (klass->name, "MethodOnTypeBuilderInst") == 0) {
+               MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
+               token = mono_image_get_method_on_inst_token (assembly, m, create_open_instance, error);
+               if (!mono_error_ok (error))
+                       return 0;
+       } else if (is_sre_array (klass) || is_sre_byref (klass) || is_sre_pointer (klass)) {
+               MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
+               return_val_if_nok (error, 0);
+               token = mono_metadata_token_from_dor (
+                               mono_image_typedef_or_ref (assembly, type));
+       } else {
+               g_error ("requested token for %s\n", klass->name);
+       }
+
+       if (register_token)
+               mono_image_register_token (assembly, token, obj);
+
+       return token;
+}
+
+
+#endif
+
+#ifndef DISABLE_REFLECTION_EMIT
+
+/*
+ * mono_reflection_dynimage_basic_init:
+ * @assembly: an assembly builder object
+ *
+ * Create the MonoImage that represents the assembly builder and setup some
+ * of the helper hash table and the basic metadata streams.
+ */
+void
+mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
+{
+       MonoError error;
+       MonoDynamicAssembly *assembly;
+       MonoDynamicImage *image;
+       MonoDomain *domain = mono_object_domain (assemblyb);
+       
+       if (assemblyb->dynamic_assembly)
+               return;
+
+#if HAVE_BOEHM_GC
+       /* assembly->assembly.image might be GC allocated */
+       assembly = assemblyb->dynamic_assembly = (MonoDynamicAssembly *)GC_MALLOC (sizeof (MonoDynamicAssembly));
+#else
+       assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
+#endif
+
+       mono_profiler_assembly_event (&assembly->assembly, MONO_PROFILE_START_LOAD);
+       
+       assembly->assembly.ref_count = 1;
+       assembly->assembly.dynamic = TRUE;
+       assembly->assembly.corlib_internal = assemblyb->corlib_internal;
+       assemblyb->assembly.assembly = (MonoAssembly*)assembly;
+       assembly->assembly.basedir = mono_string_to_utf8_checked (assemblyb->dir, &error);
+       if (mono_error_set_pending_exception (&error))
+               return;
+       if (assemblyb->culture) {
+               assembly->assembly.aname.culture = mono_string_to_utf8_checked (assemblyb->culture, &error);
+               if (mono_error_set_pending_exception (&error))
+                       return;
+       } else
+               assembly->assembly.aname.culture = g_strdup ("");
+
+        if (assemblyb->version) {
+                       char *vstr = mono_string_to_utf8_checked (assemblyb->version, &error);
+                       if (mono_error_set_pending_exception (&error))
+                               return;
+                       char **version = g_strsplit (vstr, ".", 4);
+                       char **parts = version;
+                       assembly->assembly.aname.major = atoi (*parts++);
+                       assembly->assembly.aname.minor = atoi (*parts++);
+                       assembly->assembly.aname.build = *parts != NULL ? atoi (*parts++) : 0;
+                       assembly->assembly.aname.revision = *parts != NULL ? atoi (*parts) : 0;
+
+                       g_strfreev (version);
+                       g_free (vstr);
+        } else {
+                       assembly->assembly.aname.major = 0;
+                       assembly->assembly.aname.minor = 0;
+                       assembly->assembly.aname.build = 0;
+                       assembly->assembly.aname.revision = 0;
+        }
+
+       assembly->run = assemblyb->access != 2;
+       assembly->save = assemblyb->access != 1;
+       assembly->domain = domain;
+
+       char *assembly_name = mono_string_to_utf8_checked (assemblyb->name, &error);
+       if (mono_error_set_pending_exception (&error))
+               return;
+       image = mono_dynamic_image_create (assembly, assembly_name, g_strdup ("RefEmit_YouForgotToDefineAModule"));
+       image->initial_image = TRUE;
+       assembly->assembly.aname.name = image->image.name;
+       assembly->assembly.image = &image->image;
+       if (assemblyb->pktoken && assemblyb->pktoken->max_length) {
+               /* -1 to correct for the trailing NULL byte */
+               if (assemblyb->pktoken->max_length != MONO_PUBLIC_KEY_TOKEN_LENGTH - 1) {
+                       g_error ("Public key token length invalid for assembly %s: %i", assembly->assembly.aname.name, assemblyb->pktoken->max_length);
+               }
+               memcpy (&assembly->assembly.aname.public_key_token, mono_array_addr (assemblyb->pktoken, guint8, 0), assemblyb->pktoken->max_length);           
+       }
+
+       mono_domain_assemblies_lock (domain);
+       domain->domain_assemblies = g_slist_append (domain->domain_assemblies, assembly);
+       mono_domain_assemblies_unlock (domain);
+
+       register_assembly (mono_object_domain (assemblyb), &assemblyb->assembly, &assembly->assembly);
+       
+       mono_profiler_assembly_loaded (&assembly->assembly, MONO_PROFILE_OK);
+       
+       mono_assembly_invoke_load_hook ((MonoAssembly*)assembly);
+}
+
+#endif /* !DISABLE_REFLECTION_EMIT */
+
+#ifndef DISABLE_REFLECTION_EMIT
+static gpointer
+register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly)
+{
+       CACHE_OBJECT (MonoReflectionAssembly *, assembly, res, NULL);
+}
+
+static gpointer
+register_module (MonoDomain *domain, MonoReflectionModuleBuilder *res, MonoDynamicImage *module)
+{
+       CACHE_OBJECT (MonoReflectionModuleBuilder *, module, res, NULL);
+}
+
+static gboolean
+image_module_basic_init (MonoReflectionModuleBuilder *moduleb, MonoError *error)
+{
+       MonoDynamicImage *image = moduleb->dynamic_image;
+       MonoReflectionAssemblyBuilder *ab = moduleb->assemblyb;
+       mono_error_init (error);
+       if (!image) {
+               int module_count;
+               MonoImage **new_modules;
+               MonoImage *ass;
+               char *name, *fqname;
+               /*
+                * FIXME: we already created an image in mono_reflection_dynimage_basic_init (), but
+                * we don't know which module it belongs to, since that is only 
+                * determined at assembly save time.
+                */
+               /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
+               name = mono_string_to_utf8_checked (ab->name, error);
+               return_val_if_nok (error, FALSE);
+               fqname = mono_string_to_utf8_checked (moduleb->module.fqname, error);
+               if (!is_ok (error)) {
+                       g_free (name);
+                       return FALSE;
+               }
+               image = mono_dynamic_image_create (ab->dynamic_assembly, name, fqname);
+
+               moduleb->module.image = &image->image;
+               moduleb->dynamic_image = image;
+               register_module (mono_object_domain (moduleb), moduleb, image);
+
+               /* register the module with the assembly */
+               ass = ab->dynamic_assembly->assembly.image;
+               module_count = ass->module_count;
+               new_modules = g_new0 (MonoImage *, module_count + 1);
+
+               if (ass->modules)
+                       memcpy (new_modules, ass->modules, module_count * sizeof (MonoImage *));
+               new_modules [module_count] = &image->image;
+               mono_image_addref (&image->image);
+
+               g_free (ass->modules);
+               ass->modules = new_modules;
+               ass->module_count ++;
+       }
+       return TRUE;
+}
+
+static void
+mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
+{
+       MonoError error;
+       (void) image_module_basic_init (moduleb, &error);
+       mono_error_set_pending_exception (&error);
+}
+
+#endif
+
+static gboolean
+is_corlib_type (MonoClass *klass)
+{
+       return klass->image == mono_defaults.corlib;
+}
+
+#define check_corlib_type_cached(_class, _namespace, _name) do { \
+       static MonoClass *cached_class; \
+       if (cached_class) \
+               return cached_class == _class; \
+       if (is_corlib_type (_class) && !strcmp (_name, _class->name) && !strcmp (_namespace, _class->name_space)) { \
+               cached_class = _class; \
+               return TRUE; \
+       } \
+       return FALSE; \
+} while (0) \
+
+
+
+#ifndef DISABLE_REFLECTION_EMIT
+static gboolean
+is_sre_array (MonoClass *klass)
+{
+       check_corlib_type_cached (klass, "System.Reflection.Emit", "ArrayType");
+}
+
+static gboolean
+is_sre_byref (MonoClass *klass)
+{
+       check_corlib_type_cached (klass, "System.Reflection.Emit", "ByRefType");
+}
+
+static gboolean
+is_sre_pointer (MonoClass *klass)
+{
+       check_corlib_type_cached (klass, "System.Reflection.Emit", "PointerType");
+}
+
+static gboolean
+is_sre_generic_instance (MonoClass *klass)
+{
+       check_corlib_type_cached (klass, "System.Reflection", "MonoGenericClass");
+}
+
+static gboolean
+is_sre_type_builder (MonoClass *klass)
+{
+       check_corlib_type_cached (klass, "System.Reflection.Emit", "TypeBuilder");
+}
+
+static gboolean
+is_sre_method_builder (MonoClass *klass)
+{
+       check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodBuilder");
+}
+
+gboolean
+mono_is_sre_ctor_builder (MonoClass *klass)
+{
+       check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorBuilder");
+}
+
+static gboolean
+is_sre_field_builder (MonoClass *klass)
+{
+       check_corlib_type_cached (klass, "System.Reflection.Emit", "FieldBuilder");
+}
+
+gboolean
+mono_is_sre_method_on_tb_inst (MonoClass *klass)
+{
+       check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodOnTypeBuilderInst");
+}
+
+gboolean
+mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
+{
+       check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorOnTypeBuilderInst");
+}
+
+static MonoReflectionType*
+mono_reflection_type_get_underlying_system_type (MonoReflectionType* t, MonoError *error)
+{
+       static MonoMethod *method_get_underlying_system_type = NULL;
+       MonoReflectionType *rt;
+       MonoMethod *usertype_method;
+
+       mono_error_init (error);
+
+       if (!method_get_underlying_system_type)
+               method_get_underlying_system_type = mono_class_get_method_from_name (mono_defaults.systemtype_class, "get_UnderlyingSystemType", 0);
+
+       usertype_method = mono_object_get_virtual_method ((MonoObject *) t, method_get_underlying_system_type);
+
+       rt = (MonoReflectionType *) mono_runtime_invoke_checked (usertype_method, t, NULL, error);
+
+       return rt;
+}
+
+MonoType*
+mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
+{
+       MonoClass *klass;
+       mono_error_init (error);
+
+       if (!ref)
+               return NULL;
+       if (ref->type)
+               return ref->type;
+
+       if (mono_reflection_is_usertype (ref)) {
+               ref = mono_reflection_type_get_underlying_system_type (ref, error);
+               if (ref == NULL || mono_reflection_is_usertype (ref) || !is_ok (error))
+                       return NULL;
+               if (ref->type)
+                       return ref->type;
+       }
+
+       klass = mono_object_class (ref);
+
+       if (is_sre_array (klass)) {
+               MonoType *res;
+               MonoReflectionArrayType *sre_array = (MonoReflectionArrayType*)ref;
+               MonoType *base = mono_reflection_type_get_handle (sre_array->element_type, error);
+               return_val_if_nok (error, NULL);
+               g_assert (base);
+               if (sre_array->rank == 0) //single dimentional array
+                       res = &mono_array_class_get (mono_class_from_mono_type (base), 1)->byval_arg;
+               else
+                       res = &mono_bounded_array_class_get (mono_class_from_mono_type (base), sre_array->rank, TRUE)->byval_arg;
+               sre_array->type.type = res;
+               return res;
+       } else if (is_sre_byref (klass)) {
+               MonoType *res;
+               MonoReflectionDerivedType *sre_byref = (MonoReflectionDerivedType*)ref;
+               MonoType *base = mono_reflection_type_get_handle (sre_byref->element_type, error);
+               return_val_if_nok (error, NULL);
+               g_assert (base);
+               res = &mono_class_from_mono_type (base)->this_arg;
+               sre_byref->type.type = res;
+               return res;
+       } else if (is_sre_pointer (klass)) {
+               MonoType *res;
+               MonoReflectionDerivedType *sre_pointer = (MonoReflectionDerivedType*)ref;
+               MonoType *base = mono_reflection_type_get_handle (sre_pointer->element_type, error);
+               return_val_if_nok (error, NULL);
+               g_assert (base);
+               res = &mono_ptr_class_get (base)->byval_arg;
+               sre_pointer->type.type = res;
+               return res;
+       } else if (is_sre_generic_instance (klass)) {
+               MonoType *res, **types;
+               MonoReflectionGenericClass *gclass = (MonoReflectionGenericClass*)ref;
+               int i, count;
+
+               count = mono_array_length (gclass->type_arguments);
+               types = g_new0 (MonoType*, count);
+               for (i = 0; i < count; ++i) {
+                       MonoReflectionType *t = (MonoReflectionType *)mono_array_get (gclass->type_arguments, gpointer, i);
+                       types [i] = mono_reflection_type_get_handle (t, error);
+                       if (!types[i] || !is_ok (error)) {
+                               g_free (types);
+                               return NULL;
+                       }
+               }
+
+               res = mono_reflection_bind_generic_parameters (gclass->generic_type, count, types, error);
+               g_free (types);
+               g_assert (res);
+               gclass->type.type = res;
+               return res;
+       }
+
+       g_error ("Cannot handle corlib user type %s", mono_type_full_name (&mono_object_class(ref)->byval_arg));
+       return NULL;
+}
+
+void
+ves_icall_SymbolType_create_unmanaged_type (MonoReflectionType *type)
+{
+       MonoError error;
+       mono_reflection_type_get_handle (type, &error);
+       mono_error_set_pending_exception (&error);
+}
+
+static gboolean
+reflection_register_with_runtime (MonoReflectionType *type, MonoError *error)
+{
+       MonoDomain *domain = mono_object_domain ((MonoObject*)type);
+       MonoClass *klass;
+
+       mono_error_init (error);
+
+       MonoType *res = mono_reflection_type_get_handle (type, error);
+
+       if (!res && is_ok (error)) {
+               mono_error_set_argument (error, NULL, "Invalid generic instantiation, one or more arguments are not proper user types");
+       }
+       return_val_if_nok (error, FALSE);
+
+       klass = mono_class_from_mono_type (res);
+
+       mono_loader_lock (); /*same locking as mono_type_get_object_checked */
+       mono_domain_lock (domain);
+
+       if (!image_is_dynamic (klass->image)) {
+               mono_class_setup_supertypes (klass);
+       } else {
+               if (!domain->type_hash)
+                       domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mono_metadata_type_hash, 
+                                       (GCompareFunc)mono_metadata_type_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection types table");
+               mono_g_hash_table_insert (domain->type_hash, res, type);
+       }
+       mono_domain_unlock (domain);
+       mono_loader_unlock ();
+
+       return TRUE;
+}
+
+void
+mono_reflection_register_with_runtime (MonoReflectionType *type)
+{
+       MonoError error;
+       (void) reflection_register_with_runtime (type, &error);
+       mono_error_set_pending_exception (&error);
+}
+
+/**
+ * LOCKING: Assumes the loader lock is held.
+ */
+static MonoMethodSignature*
+parameters_to_signature (MonoImage *image, MonoArray *parameters, MonoError *error) {
+       MonoMethodSignature *sig;
+       int count, i;
+
+       mono_error_init (error);
+
+       count = parameters? mono_array_length (parameters): 0;
+
+       sig = (MonoMethodSignature *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * count);
+       sig->param_count = count;
+       sig->sentinelpos = -1; /* FIXME */
+       for (i = 0; i < count; ++i) {
+               sig->params [i] = mono_type_array_get_and_resolve (parameters, i, error);
+               if (!is_ok (error)) {
+                       image_g_free (image, sig);
+                       return NULL;
+               }
+       }
+       return sig;
+}
+
+/**
+ * LOCKING: Assumes the loader lock is held.
+ */
+static MonoMethodSignature*
+ctor_builder_to_signature (MonoImage *image, MonoReflectionCtorBuilder *ctor, MonoError *error) {
+       MonoMethodSignature *sig;
+
+       mono_error_init (error);
+
+       sig = parameters_to_signature (image, ctor->parameters, error);
+       return_val_if_nok (error, NULL);
+       sig->hasthis = ctor->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
+       sig->ret = &mono_defaults.void_class->byval_arg;
+       return sig;
+}
+
+/**
+ * LOCKING: Assumes the loader lock is held.
+ */
+static MonoMethodSignature*
+method_builder_to_signature (MonoImage *image, MonoReflectionMethodBuilder *method, MonoError *error) {
+       MonoMethodSignature *sig;
+
+       mono_error_init (error);
+
+       sig = parameters_to_signature (image, method->parameters, error);
+       return_val_if_nok (error, NULL);
+       sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
+       if (method->rtype) {
+               sig->ret = mono_reflection_type_get_handle ((MonoReflectionType*)method->rtype, error);
+               if (!is_ok (error)) {
+                       image_g_free (image, sig);
+                       return NULL;
+               }
+       } else {
+               sig->ret = &mono_defaults.void_class->byval_arg;
+       }
+       sig->generic_param_count = method->generic_params ? mono_array_length (method->generic_params) : 0;
+       return sig;
+}
+
+static MonoMethodSignature*
+dynamic_method_to_signature (MonoReflectionDynamicMethod *method, MonoError *error) {
+       MonoMethodSignature *sig;
+
+       mono_error_init (error);
+
+       sig = parameters_to_signature (NULL, method->parameters, error);
+       return_val_if_nok (error, NULL);
+       sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
+       if (method->rtype) {
+               sig->ret = mono_reflection_type_get_handle (method->rtype, error);
+               if (!is_ok (error)) {
+                       g_free (sig);
+                       return NULL;
+               }
+       } else {
+               sig->ret = &mono_defaults.void_class->byval_arg;
+       }
+       sig->generic_param_count = 0;
+       return sig;
+}
+
+static void
+get_prop_name_and_type (MonoObject *prop, char **name, MonoType **type, MonoError *error)
+{
+       mono_error_init (error);
+       MonoClass *klass = mono_object_class (prop);
+       if (strcmp (klass->name, "PropertyBuilder") == 0) {
+               MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *)prop;
+               *name = mono_string_to_utf8_checked (pb->name, error);
+               return_if_nok (error);
+               *type = mono_reflection_type_get_handle ((MonoReflectionType*)pb->type, error);
+       } else {
+               MonoReflectionProperty *p = (MonoReflectionProperty *)prop;
+               *name = g_strdup (p->property->name);
+               if (p->property->get)
+                       *type = mono_method_signature (p->property->get)->ret;
+               else
+                       *type = mono_method_signature (p->property->set)->params [mono_method_signature (p->property->set)->param_count - 1];
+       }
+}
+
+static void
+get_field_name_and_type (MonoObject *field, char **name, MonoType **type, MonoError *error)
+{
+       mono_error_init (error);
+       MonoClass *klass = mono_object_class (field);
+       if (strcmp (klass->name, "FieldBuilder") == 0) {
+               MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)field;
+               *name = mono_string_to_utf8_checked (fb->name, error);
+               return_if_nok (error);
+               *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
+       } else {
+               MonoReflectionField *f = (MonoReflectionField *)field;
+               *name = g_strdup (mono_field_get_name (f->field));
+               *type = f->field->type;
+       }
+}
+
+#else /* DISABLE_REFLECTION_EMIT */
+
+void
+mono_reflection_register_with_runtime (MonoReflectionType *type)
+{
+       /* This is empty */
+}
+
+static gboolean
+is_sre_type_builder (MonoClass *klass)
+{
+       return FALSE;
+}
+
+static gboolean
+is_sre_generic_instance (MonoClass *klass)
+{
+       return FALSE;
+}
+
+gboolean
+mono_is_sre_ctor_builder (MonoClass *klass)
+{
+       return FALSE;
+}
+
+gboolean
+mono_is_sre_method_on_tb_inst (MonoClass *klass)
+{
+       return FALSE;
+}
+
+gboolean
+mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
+{
+       return FALSE;
+}
+
+void
+mono_reflection_init_type_builder_generics (MonoObject *type, MonoError *error)
+{
+       mono_error_init (error);
+}
+
+#endif /* !DISABLE_REFLECTION_EMIT */
+
+
+static gboolean
+is_sr_mono_field (MonoClass *klass)
+{
+       check_corlib_type_cached (klass, "System.Reflection", "MonoField");
+}
+
+gboolean
+mono_is_sr_mono_property (MonoClass *klass)
+{
+       check_corlib_type_cached (klass, "System.Reflection", "MonoProperty");
+}
+
+static gboolean
+is_sr_mono_method (MonoClass *klass)
+{
+       check_corlib_type_cached (klass, "System.Reflection", "MonoMethod");
+}
+
+gboolean
+mono_is_sr_mono_cmethod (MonoClass *klass)
+{
+       check_corlib_type_cached (klass, "System.Reflection", "MonoCMethod");
+}
+
+static gboolean
+is_sr_mono_generic_method (MonoClass *klass)
+{
+       check_corlib_type_cached (klass, "System.Reflection", "MonoGenericMethod");
+}
+
+static gboolean
+is_sr_mono_generic_cmethod (MonoClass *klass)
+{
+       check_corlib_type_cached (klass, "System.Reflection", "MonoGenericCMethod");
+}
+
+gboolean
+mono_class_is_reflection_method_or_constructor (MonoClass *klass)
+{
+       return is_sr_mono_method (klass) || mono_is_sr_mono_cmethod (klass) || is_sr_mono_generic_method (klass) || is_sr_mono_generic_cmethod (klass);
+}
+
+gboolean
+mono_is_sre_type_builder (MonoClass *klass)
+{
+       return is_sre_type_builder (klass);
+}
+
+gboolean
+mono_is_sre_generic_instance (MonoClass *klass)
+{
+       return is_sre_generic_instance (klass);
+}
+
+
+
+/**
+ * encode_cattr_value:
+ * Encode a value in a custom attribute stream of bytes.
+ * The value to encode is either supplied as an object in argument val
+ * (valuetypes are boxed), or as a pointer to the data in the
+ * argument argval.
+ * @type represents the type of the value
+ * @buffer is the start of the buffer
+ * @p the current position in the buffer
+ * @buflen contains the size of the buffer and is used to return the new buffer size
+ * if this needs to be realloced.
+ * @retbuffer and @retp return the start and the position of the buffer
+ * @error set on error.
+ */
+static void
+encode_cattr_value (MonoAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg, char *argval, MonoError *error)
+{
+       MonoTypeEnum simple_type;
+       
+       mono_error_init (error);
+       if ((p-buffer) + 10 >= *buflen) {
+               char *newbuf;
+               *buflen *= 2;
+               newbuf = (char *)g_realloc (buffer, *buflen);
+               p = newbuf + (p-buffer);
+               buffer = newbuf;
+       }
+       if (!argval)
+               argval = ((char*)arg + sizeof (MonoObject));
+       simple_type = type->type;
+handle_enum:
+       switch (simple_type) {
+       case MONO_TYPE_BOOLEAN:
+       case MONO_TYPE_U1:
+       case MONO_TYPE_I1:
+               *p++ = *argval;
+               break;
+       case MONO_TYPE_CHAR:
+       case MONO_TYPE_U2:
+       case MONO_TYPE_I2:
+               swap_with_size (p, argval, 2, 1);
+               p += 2;
+               break;
+       case MONO_TYPE_U4:
+       case MONO_TYPE_I4:
+       case MONO_TYPE_R4:
+               swap_with_size (p, argval, 4, 1);
+               p += 4;
+               break;
+       case MONO_TYPE_R8:
+               swap_with_size (p, argval, 8, 1);
+               p += 8;
+               break;
+       case MONO_TYPE_U8:
+       case MONO_TYPE_I8:
+               swap_with_size (p, argval, 8, 1);
+               p += 8;
+               break;
+       case MONO_TYPE_VALUETYPE:
+               if (type->data.klass->enumtype) {
+                       simple_type = mono_class_enum_basetype (type->data.klass)->type;
+                       goto handle_enum;
+               } else {
+                       g_warning ("generic valutype %s not handled in custom attr value decoding", type->data.klass->name);
+               }
+               break;
+       case MONO_TYPE_STRING: {
+               char *str;
+               guint32 slen;
+               if (!arg) {
+                       *p++ = 0xFF;
+                       break;
+               }
+               str = mono_string_to_utf8_checked ((MonoString*)arg, error);
+               return_if_nok (error);
+               slen = strlen (str);
+               if ((p-buffer) + 10 + slen >= *buflen) {
+                       char *newbuf;
+                       *buflen *= 2;
+                       *buflen += slen;
+                       newbuf = (char *)g_realloc (buffer, *buflen);
+                       p = newbuf + (p-buffer);
+                       buffer = newbuf;
+               }
+               mono_metadata_encode_value (slen, p, &p);
+               memcpy (p, str, slen);
+               p += slen;
+               g_free (str);
+               break;
+       }
+       case MONO_TYPE_CLASS: {
+               char *str;
+               guint32 slen;
+               MonoType *arg_type;
+               if (!arg) {
+                       *p++ = 0xFF;
+                       break;
+               }
+handle_type:
+               arg_type = mono_reflection_type_get_handle ((MonoReflectionType*)arg, error);
+               return_if_nok (error);
+
+               str = type_get_qualified_name (arg_type, NULL);
+               slen = strlen (str);
+               if ((p-buffer) + 10 + slen >= *buflen) {
+                       char *newbuf;
+                       *buflen *= 2;
+                       *buflen += slen;
+                       newbuf = (char *)g_realloc (buffer, *buflen);
+                       p = newbuf + (p-buffer);
+                       buffer = newbuf;
+               }
+               mono_metadata_encode_value (slen, p, &p);
+               memcpy (p, str, slen);
+               p += slen;
+               g_free (str);
+               break;
+       }
+       case MONO_TYPE_SZARRAY: {
+               int len, i;
+               MonoClass *eclass, *arg_eclass;
+
+               if (!arg) {
+                       *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p++ = 0xff;
+                       break;
+               }
+               len = mono_array_length ((MonoArray*)arg);
+               *p++ = len & 0xff;
+               *p++ = (len >> 8) & 0xff;
+               *p++ = (len >> 16) & 0xff;
+               *p++ = (len >> 24) & 0xff;
+               *retp = p;
+               *retbuffer = buffer;
+               eclass = type->data.klass;
+               arg_eclass = mono_object_class (arg)->element_class;
+
+               if (!eclass) {
+                       /* Happens when we are called from the MONO_TYPE_OBJECT case below */
+                       eclass = mono_defaults.object_class;
+               }
+               if (eclass == mono_defaults.object_class && arg_eclass->valuetype) {
+                       char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
+                       int elsize = mono_class_array_element_size (arg_eclass);
+                       for (i = 0; i < len; ++i) {
+                               encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &arg_eclass->byval_arg, NULL, elptr, error);
+                               return_if_nok (error);
+                               elptr += elsize;
+                       }
+               } else if (eclass->valuetype && arg_eclass->valuetype) {
+                       char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
+                       int elsize = mono_class_array_element_size (eclass);
+                       for (i = 0; i < len; ++i) {
+                               encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, NULL, elptr, error);
+                               return_if_nok (error);
+                               elptr += elsize;
+                       }
+               } else {
+                       for (i = 0; i < len; ++i) {
+                               encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i), NULL, error);
+                               return_if_nok (error);
+                       }
+               }
+               break;
+       }
+       case MONO_TYPE_OBJECT: {
+               MonoClass *klass;
+               char *str;
+               guint32 slen;
+
+               /*
+                * The parameter type is 'object' but the type of the actual
+                * argument is not. So we have to add type information to the blob
+                * too. This is completely undocumented in the spec.
+                */
+
+               if (arg == NULL) {
+                       *p++ = MONO_TYPE_STRING;        // It's same hack as MS uses
+                       *p++ = 0xFF;
+                       break;
+               }
+               
+               klass = mono_object_class (arg);
+
+               if (mono_object_isinst_checked (arg, mono_defaults.systemtype_class, error)) {
+                       *p++ = 0x50;
+                       goto handle_type;
+               } else {
+                       return_if_nok (error);
+               }
+
+               if (klass->enumtype) {
+                       *p++ = 0x55;
+               } else if (klass == mono_defaults.string_class) {
+                       simple_type = MONO_TYPE_STRING;
+                       *p++ = 0x0E;
+                       goto handle_enum;
+               } else if (klass->rank == 1) {
+                       *p++ = 0x1D;
+                       if (klass->element_class->byval_arg.type == MONO_TYPE_OBJECT)
+                               /* See Partition II, Appendix B3 */
+                               *p++ = 0x51;
+                       else
+                               *p++ = klass->element_class->byval_arg.type;
+                       encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &klass->byval_arg, arg, NULL, error);
+                       return_if_nok (error);
+                       break;
+               } else if (klass->byval_arg.type >= MONO_TYPE_BOOLEAN && klass->byval_arg.type <= MONO_TYPE_R8) {
+                       *p++ = simple_type = klass->byval_arg.type;
+                       goto handle_enum;
+               } else {
+                       g_error ("unhandled type in custom attr");
+               }
+               str = type_get_qualified_name (mono_class_get_type(klass), NULL);
+               slen = strlen (str);
+               if ((p-buffer) + 10 + slen >= *buflen) {
+                       char *newbuf;
+                       *buflen *= 2;
+                       *buflen += slen;
+                       newbuf = (char *)g_realloc (buffer, *buflen);
+                       p = newbuf + (p-buffer);
+                       buffer = newbuf;
+               }
+               mono_metadata_encode_value (slen, p, &p);
+               memcpy (p, str, slen);
+               p += slen;
+               g_free (str);
+               simple_type = mono_class_enum_basetype (klass)->type;
+               goto handle_enum;
+       }
+       default:
+               g_error ("type 0x%02x not yet supported in custom attr encoder", simple_type);
+       }
+       *retp = p;
+       *retbuffer = buffer;
+}
+
+static void
+encode_field_or_prop_type (MonoType *type, char *p, char **retp)
+{
+       if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
+               char *str = type_get_qualified_name (type, NULL);
+               int slen = strlen (str);
+
+               *p++ = 0x55;
+               /*
+                * This seems to be optional...
+                * *p++ = 0x80;
+                */
+               mono_metadata_encode_value (slen, p, &p);
+               memcpy (p, str, slen);
+               p += slen;
+               g_free (str);
+       } else if (type->type == MONO_TYPE_OBJECT) {
+               *p++ = 0x51;
+       } else if (type->type == MONO_TYPE_CLASS) {
+               /* it should be a type: encode_cattr_value () has the check */
+               *p++ = 0x50;
+       } else {
+               mono_metadata_encode_value (type->type, p, &p);
+               if (type->type == MONO_TYPE_SZARRAY)
+                       /* See the examples in Partition VI, Annex B */
+                       encode_field_or_prop_type (&type->data.klass->byval_arg, p, &p);
+       }
+
+       *retp = p;
+}
+
+#ifndef DISABLE_REFLECTION_EMIT
+static void
+encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, char *name, MonoObject *value, MonoError *error)
+{
+       int len;
+
+       mono_error_init (error);
+
+       /* Preallocate a large enough buffer */
+       if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
+               char *str = type_get_qualified_name (type, NULL);
+               len = strlen (str);
+               g_free (str);
+       } else if (type->type == MONO_TYPE_SZARRAY && type->data.klass->enumtype) {
+               char *str = type_get_qualified_name (&type->data.klass->byval_arg, NULL);
+               len = strlen (str);
+               g_free (str);
+       } else {
+               len = 0;
+       }
+       len += strlen (name);
+
+       if ((p-buffer) + 20 + len >= *buflen) {
+               char *newbuf;
+               *buflen *= 2;
+               *buflen += len;
+               newbuf = (char *)g_realloc (buffer, *buflen);
+               p = newbuf + (p-buffer);
+               buffer = newbuf;
+       }
+
+       encode_field_or_prop_type (type, p, &p);
+
+       len = strlen (name);
+       mono_metadata_encode_value (len, p, &p);
+       memcpy (p, name, len);
+       p += len;
+       encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, buflen, type, value, NULL, error);
+       return_if_nok (error);
+       *retp = p;
+       *retbuffer = buffer;
+}
+
+/**
+ * mono_reflection_get_custom_attrs_blob:
+ * @ctor: custom attribute constructor
+ * @ctorArgs: arguments o the constructor
+ * @properties:
+ * @propValues:
+ * @fields:
+ * @fieldValues:
+ * 
+ * Creates the blob of data that needs to be saved in the metadata and that represents
+ * the custom attributed described by @ctor, @ctorArgs etc.
+ * Returns: a Byte array representing the blob of data.
+ */
+MonoArray*
+mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) 
+{
+       MonoError error;
+       MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
+       mono_error_cleanup (&error);
+       return result;
+}
+
+/**
+ * mono_reflection_get_custom_attrs_blob_checked:
+ * @ctor: custom attribute constructor
+ * @ctorArgs: arguments o the constructor
+ * @properties:
+ * @propValues:
+ * @fields:
+ * @fieldValues:
+ * @error: set on error
+ * 
+ * Creates the blob of data that needs to be saved in the metadata and that represents
+ * the custom attributed described by @ctor, @ctorArgs etc.
+ * Returns: a Byte array representing the blob of data.  On failure returns NULL and sets @error.
+ */
+MonoArray*
+mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues, MonoError *error) 
+{
+       MonoArray *result = NULL;
+       MonoMethodSignature *sig;
+       MonoObject *arg;
+       char *buffer, *p;
+       guint32 buflen, i;
+
+       mono_error_init (error);
+
+       if (strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
+               /* sig is freed later so allocate it in the heap */
+               sig = ctor_builder_to_signature (NULL, (MonoReflectionCtorBuilder*)ctor, error);
+               if (!is_ok (error)) {
+                       g_free (sig);
+                       return NULL;
+               }
+       } else {
+               sig = mono_method_signature (((MonoReflectionMethod*)ctor)->method);
+       }
+
+       g_assert (mono_array_length (ctorArgs) == sig->param_count);
+       buflen = 256;
+       p = buffer = (char *)g_malloc (buflen);
+       /* write the prolog */
+       *p++ = 1;
+       *p++ = 0;
+       for (i = 0; i < sig->param_count; ++i) {
+               arg = mono_array_get (ctorArgs, MonoObject*, i);
+               encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, sig->params [i], arg, NULL, error);
+               if (!is_ok (error)) goto leave;
+       }
+       i = 0;
+       if (properties)
+               i += mono_array_length (properties);
+       if (fields)
+               i += mono_array_length (fields);
+       *p++ = i & 0xff;
+       *p++ = (i >> 8) & 0xff;
+       if (properties) {
+               MonoObject *prop;
+               for (i = 0; i < mono_array_length (properties); ++i) {
+                       MonoType *ptype;
+                       char *pname;
+
+                       prop = (MonoObject *)mono_array_get (properties, gpointer, i);
+                       get_prop_name_and_type (prop, &pname, &ptype, error);
+                       if (!is_ok (error)) goto leave;
+                       *p++ = 0x54; /* PROPERTY signature */
+                       encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ptype, pname, (MonoObject*)mono_array_get (propValues, gpointer, i), error);
+                       g_free (pname);
+                       if (!is_ok (error)) goto leave;
+               }
+       }
+
+       if (fields) {
+               MonoObject *field;
+               for (i = 0; i < mono_array_length (fields); ++i) {
+                       MonoType *ftype;
+                       char *fname;
+
+                       field = (MonoObject *)mono_array_get (fields, gpointer, i);
+                       get_field_name_and_type (field, &fname, &ftype, error);
+                       if (!is_ok (error)) goto leave;
+                       *p++ = 0x53; /* FIELD signature */
+                       encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ftype, fname, (MonoObject*)mono_array_get (fieldValues, gpointer, i), error);
+                       g_free (fname);
+                       if (!is_ok (error)) goto leave;
+               }
+       }
+
+       g_assert (p - buffer <= buflen);
+       buflen = p - buffer;
+       result = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, buflen, error);
+       if (!is_ok (error))
+               goto leave;
+       p = mono_array_addr (result, char, 0);
+       memcpy (p, buffer, buflen);
+leave:
+       g_free (buffer);
+       if (strcmp (ctor->vtable->klass->name, "MonoCMethod"))
+               g_free (sig);
+       return result;
+}
+
+/**
+ * reflection_setup_internal_class:
+ * @tb: a TypeBuilder object
+ * @error: set on error
+ *
+ * Creates a MonoClass that represents the TypeBuilder.
+ * This is a trick that lets us simplify a lot of reflection code
+ * (and will allow us to support Build and Run assemblies easier).
+ *
+ * Returns TRUE on success. On failure, returns FALSE and sets @error.
+ */
+static gboolean
+reflection_setup_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error)
+{
+       MonoClass *klass, *parent;
+
+       mono_error_init (error);
+
+       mono_loader_lock ();
+
+       if (tb->parent) {
+               MonoType *parent_type = mono_reflection_type_get_handle ((MonoReflectionType*)tb->parent, error);
+               if (!is_ok (error)) {
+                       mono_loader_unlock ();
+                       return FALSE;
+               }
+               /* check so we can compile corlib correctly */
+               if (strcmp (mono_object_class (tb->parent)->name, "TypeBuilder") == 0) {
+                       /* mono_class_setup_mono_type () guaranteess type->data.klass is valid */
+                       parent = parent_type->data.klass;
+               } else {
+                       parent = mono_class_from_mono_type (parent_type);
+               }
+       } else {
+               parent = NULL;
+       }
+       
+       /* the type has already being created: it means we just have to change the parent */
+       if (tb->type.type) {
+               klass = mono_class_from_mono_type (tb->type.type);
+               klass->parent = NULL;
+               /* fool mono_class_setup_parent */
+               klass->supertypes = NULL;
+               mono_class_setup_parent (klass, parent);
+               mono_class_setup_mono_type (klass);
+               mono_loader_unlock ();
+               return TRUE;
+       }
+
+       klass = (MonoClass *)mono_image_alloc0 (&tb->module->dynamic_image->image, sizeof (MonoClass));
+
+       klass->image = &tb->module->dynamic_image->image;
+
+       klass->inited = 1; /* we lie to the runtime */
+       klass->name = mono_string_to_utf8_image (klass->image, tb->name, error);
+       if (!is_ok (error))
+               goto failure;
+       klass->name_space = mono_string_to_utf8_image (klass->image, tb->nspace, error);
+       if (!is_ok (error))
+               goto failure;
+       klass->type_token = MONO_TOKEN_TYPE_DEF | tb->table_idx;
+       klass->flags = tb->attrs;
+       
+       mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD);
+
+       klass->element_class = klass;
+
+       if (mono_class_get_ref_info (klass) == NULL) {
+               mono_class_set_ref_info (klass, tb);
+
+               /* Put into cache so mono_class_get_checked () will find it.
+               Skip nested types as those should not be available on the global scope. */
+               if (!tb->nesting_type)
+                       mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, tb->table_idx);
+
+               /*
+               We must register all types as we cannot rely on the name_cache hashtable since we find the class
+               by performing a mono_class_get which does the full resolution.
+
+               Working around this semantics would require us to write a lot of code for no clear advantage.
+               */
+               mono_image_append_class_to_reflection_info_set (klass);
+       } else {
+               g_assert (mono_class_get_ref_info (klass) == tb);
+       }
+
+       mono_dynamic_image_register_token (tb->module->dynamic_image, MONO_TOKEN_TYPE_DEF | tb->table_idx, (MonoObject*)tb);
+
+       if (parent != NULL) {
+               mono_class_setup_parent (klass, parent);
+       } else if (strcmp (klass->name, "Object") == 0 && strcmp (klass->name_space, "System") == 0) {
+               const char *old_n = klass->name;
+               /* trick to get relative numbering right when compiling corlib */
+               klass->name = "BuildingObject";
+               mono_class_setup_parent (klass, mono_defaults.object_class);
+               klass->name = old_n;
+       }
+
+       if ((!strcmp (klass->name, "ValueType") && !strcmp (klass->name_space, "System")) ||
+                       (!strcmp (klass->name, "Object") && !strcmp (klass->name_space, "System")) ||
+                       (!strcmp (klass->name, "Enum") && !strcmp (klass->name_space, "System"))) {
+               klass->instance_size = sizeof (MonoObject);
+               klass->size_inited = 1;
+               mono_class_setup_vtable_general (klass, NULL, 0, NULL);
+       }
+
+       mono_class_setup_mono_type (klass);
+
+       mono_class_setup_supertypes (klass);
+
+       /*
+        * FIXME: handle interfaces.
+        */
+
+       tb->type.type = &klass->byval_arg;
+
+       if (tb->nesting_type) {
+               g_assert (tb->nesting_type->type);
+               MonoType *nesting_type = mono_reflection_type_get_handle (tb->nesting_type, error);
+               if (!is_ok (error)) goto failure;
+               klass->nested_in = mono_class_from_mono_type (nesting_type);
+       }
+
+       /*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
+
+       mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
+       
+       mono_loader_unlock ();
+       return TRUE;
+
+failure:
+       mono_loader_unlock ();
+       return FALSE;
+}
+
+/**
+ * ves_icall_TypeBuilder_setup_internal_class:
+ * @tb: a TypeBuilder object
+ *
+ * (icall)
+ * Creates a MonoClass that represents the TypeBuilder.
+ * This is a trick that lets us simplify a lot of reflection code
+ * (and will allow us to support Build and Run assemblies easier).
+ *
+ */
+void
+ves_icall_TypeBuilder_setup_internal_class (MonoReflectionTypeBuilder *tb)
+{
+       MonoError error;
+       (void) reflection_setup_internal_class (tb, &error);
+       mono_error_set_pending_exception (&error);
+}
+
+/**
+ * mono_reflection_create_generic_class:
+ * @tb: a TypeBuilder object
+ * @error: set on error
+ *
+ * Creates the generic class after all generic parameters have been added.
+ * On success returns TRUE, on failure returns FALSE and sets @error.
+ * 
+ */
+gboolean
+mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error)
+{
+
+       MonoClass *klass;
+       int count, i;
+
+       mono_error_init (error);
+
+       klass = mono_class_from_mono_type (tb->type.type);
+
+       count = tb->generic_params ? mono_array_length (tb->generic_params) : 0;
+
+       if (klass->generic_container || (count == 0))
+               return TRUE;
+
+       g_assert (tb->generic_container && (tb->generic_container->owner.klass == klass));
+
+       klass->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
+
+       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->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;
+               /*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;
+
+               g_assert (klass->generic_container->type_params [i].param.owner);
+       }
+
+       klass->generic_container->context.class_inst = mono_get_shared_generic_inst (klass->generic_container);
+       return TRUE;
+}
+
+static MonoMarshalSpec*
+mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
+                               MonoReflectionMarshal *minfo, MonoError *error)
+{
+       MonoMarshalSpec *res;
+
+       mono_error_init (error);
+
+       res = image_g_new0 (image, MonoMarshalSpec, 1);
+       res->native = (MonoMarshalNative)minfo->type;
+
+       switch (minfo->type) {
+       case MONO_NATIVE_LPARRAY:
+               res->data.array_data.elem_type = (MonoMarshalNative)minfo->eltype;
+               if (minfo->has_size) {
+                       res->data.array_data.param_num = minfo->param_num;
+                       res->data.array_data.num_elem = minfo->count;
+                       res->data.array_data.elem_mult = minfo->param_num == -1 ? 0 : 1;
+               }
+               else {
+                       res->data.array_data.param_num = -1;
+                       res->data.array_data.num_elem = -1;
+                       res->data.array_data.elem_mult = -1;
+               }
+               break;
+
+       case MONO_NATIVE_BYVALTSTR:
+       case MONO_NATIVE_BYVALARRAY:
+               res->data.array_data.num_elem = minfo->count;
+               break;
+
+       case MONO_NATIVE_CUSTOM:
+               if (minfo->marshaltyperef) {
+                       MonoType *marshaltyperef = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
+                       if (!is_ok (error)) {
+                               image_g_free (image, res);
+                               return NULL;
+                       }
+                       res->data.custom_data.custom_name =
+                               type_get_fully_qualified_name (marshaltyperef);
+               }
+               if (minfo->mcookie) {
+                       res->data.custom_data.cookie = mono_string_to_utf8_checked (minfo->mcookie, error);
+                       if (!is_ok (error)) {
+                               image_g_free (image, res);
+                               return NULL;
+                       }
+               }
+               break;
+
+       default:
+               break;
+       }
+
+       return res;
+}
+#endif /* !DISABLE_REFLECTION_EMIT */
+
+MonoReflectionMarshalAsAttribute*
+mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
+                                                       MonoMarshalSpec *spec, MonoError *error)
+{
+       MonoReflectionType *rt;
+       MonoReflectionMarshalAsAttribute *minfo;
+       MonoType *mtype;
+
+       mono_error_init (error);
+       
+       minfo = (MonoReflectionMarshalAsAttribute*)mono_object_new_checked (domain, mono_class_get_marshal_as_attribute_class (), error);
+       if (!minfo)
+               return NULL;
+       minfo->utype = spec->native;
+
+       switch (minfo->utype) {
+       case MONO_NATIVE_LPARRAY:
+               minfo->array_subtype = spec->data.array_data.elem_type;
+               minfo->size_const = spec->data.array_data.num_elem;
+               if (spec->data.array_data.param_num != -1)
+                       minfo->size_param_index = spec->data.array_data.param_num;
+               break;
+
+       case MONO_NATIVE_BYVALTSTR:
+       case MONO_NATIVE_BYVALARRAY:
+               minfo->size_const = spec->data.array_data.num_elem;
+               break;
+
+       case MONO_NATIVE_CUSTOM:
+               if (spec->data.custom_data.custom_name) {
+                       mtype = mono_reflection_type_from_name_checked (spec->data.custom_data.custom_name, klass->image, error);
+                       return_val_if_nok  (error, NULL);
+
+                       if (mtype) {
+                               rt = mono_type_get_object_checked (domain, mtype, error);
+                               if (!rt)
+                                       return NULL;
+
+                               MONO_OBJECT_SETREF (minfo, marshal_type_ref, rt);
+                       }
+
+                       MONO_OBJECT_SETREF (minfo, marshal_type, mono_string_new (domain, spec->data.custom_data.custom_name));
+               }
+               if (spec->data.custom_data.cookie)
+                       MONO_OBJECT_SETREF (minfo, marshal_cookie, mono_string_new (domain, spec->data.custom_data.cookie));
+               break;
+
+       default:
+               break;
+       }
+
+       return minfo;
+}
+
+#ifndef DISABLE_REFLECTION_EMIT
+static MonoMethod*
+reflection_methodbuilder_to_mono_method (MonoClass *klass,
+                                        ReflectionMethodBuilder *rmb,
+                                        MonoMethodSignature *sig,
+                                        MonoError *error)
+{
+       MonoMethod *m;
+       MonoMethodWrapper *wrapperm;
+       MonoMarshalSpec **specs;
+       MonoReflectionMethodAux *method_aux;
+       MonoImage *image;
+       gboolean dynamic;
+       int i;
+
+       mono_error_init (error);
+       /*
+        * Methods created using a MethodBuilder should have their memory allocated
+        * inside the image mempool, while dynamic methods should have their memory
+        * malloc'd.
+        */
+       dynamic = rmb->refs != NULL;
+       image = dynamic ? NULL : klass->image;
+
+       if (!dynamic)
+               g_assert (!klass->generic_class);
+
+       mono_loader_lock ();
+
+       if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
+                       (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
+               m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1);
+       else
+               m = (MonoMethod *)image_g_new0 (image, MonoMethodWrapper, 1);
+
+       wrapperm = (MonoMethodWrapper*)m;
+
+       m->dynamic = dynamic;
+       m->slot = -1;
+       m->flags = rmb->attrs;
+       m->iflags = rmb->iattrs;
+       m->name = mono_string_to_utf8_image_ignore (image, rmb->name);
+       m->klass = klass;
+       m->signature = sig;
+       m->sre_method = TRUE;
+       m->skip_visibility = rmb->skip_visibility;
+       if (rmb->table_idx)
+               m->token = MONO_TOKEN_METHOD_DEF | (*rmb->table_idx);
+
+       if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
+               if (klass == mono_defaults.string_class && !strcmp (m->name, ".ctor"))
+                       m->string_ctor = 1;
+
+               m->signature->pinvoke = 1;
+       } else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
+               m->signature->pinvoke = 1;
+
+               method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
+
+               method_aux->dllentry = rmb->dllentry ? mono_string_to_utf8_image (image, rmb->dllentry, error) : image_strdup (image, m->name);
+               mono_error_assert_ok (error);
+               method_aux->dll = mono_string_to_utf8_image (image, rmb->dll, error);
+               mono_error_assert_ok (error);
+               
+               ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags;
+
+               if (image_is_dynamic (klass->image))
+                       g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
+
+               mono_loader_unlock ();
+
+               return m;
+       } else if (!(m->flags & METHOD_ATTRIBUTE_ABSTRACT) &&
+                          !(m->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
+               MonoMethodHeader *header;
+               guint32 code_size;
+               gint32 max_stack, i;
+               gint32 num_locals = 0;
+               gint32 num_clauses = 0;
+               guint8 *code;
+
+               if (rmb->ilgen) {
+                       code = mono_array_addr (rmb->ilgen->code, guint8, 0);
+                       code_size = rmb->ilgen->code_len;
+                       max_stack = rmb->ilgen->max_stack;
+                       num_locals = rmb->ilgen->locals ? mono_array_length (rmb->ilgen->locals) : 0;
+                       if (rmb->ilgen->ex_handlers)
+                               num_clauses = mono_reflection_method_count_clauses (rmb->ilgen);
+               } else {
+                       if (rmb->code) {
+                               code = mono_array_addr (rmb->code, guint8, 0);
+                               code_size = mono_array_length (rmb->code);
+                               /* we probably need to run a verifier on the code... */
+                               max_stack = 8; 
+                       }
+                       else {
+                               code = NULL;
+                               code_size = 0;
+                               max_stack = 8;
+                       }
+               }
+
+               header = (MonoMethodHeader *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_HEADER + num_locals * sizeof (MonoType*));
+               header->code_size = code_size;
+               header->code = (const unsigned char *)image_g_malloc (image, code_size);
+               memcpy ((char*)header->code, code, code_size);
+               header->max_stack = max_stack;
+               header->init_locals = rmb->init_locals;
+               header->num_locals = num_locals;
+
+               for (i = 0; i < num_locals; ++i) {
+                       MonoReflectionLocalBuilder *lb = 
+                               mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
+
+                       header->locals [i] = image_g_new0 (image, MonoType, 1);
+                       MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)lb->type, error);
+                       mono_error_assert_ok (error);
+                       memcpy (header->locals [i], type, MONO_SIZEOF_TYPE);
+               }
+
+               header->num_clauses = num_clauses;
+               if (num_clauses) {
+                       header->clauses = method_encode_clauses (image, (MonoDynamicImage*)klass->image,
+                                                                rmb->ilgen, num_clauses, error);
+                       mono_error_assert_ok (error);
+               }
+
+               wrapperm->header = header;
+       }
+
+       if (rmb->generic_params) {
+               int count = mono_array_length (rmb->generic_params);
+               MonoGenericContainer *container = rmb->generic_container;
+
+               g_assert (container);
+
+               container->type_argc = count;
+               container->type_params = image_g_new0 (image, MonoGenericParamFull, count);
+               container->owner.method = m;
+               container->is_anonymous = FALSE; // Method is now known, container is no longer anonymous
+
+               m->is_generic = TRUE;
+               mono_method_set_generic_container (m, container);
+
+               for (i = 0; i < count; i++) {
+                       MonoReflectionGenericParam *gp =
+                               mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
+                       MonoType *gp_type = mono_reflection_type_get_handle ((MonoReflectionType*)gp, error);
+                       mono_error_assert_ok (error);
+                       MonoGenericParamFull *param = (MonoGenericParamFull *) gp_type->data.generic_param;
+                       container->type_params [i] = *param;
+               }
+
+               /*
+                * The method signature might have pointers to generic parameters that belong to other methods.
+                * This is a valid SRE case, but the resulting method signature must be encoded using the proper
+                * generic parameters.
+                */
+               for (i = 0; i < m->signature->param_count; ++i) {
+                       MonoType *t = m->signature->params [i];
+                       if (t->type == MONO_TYPE_MVAR) {
+                               MonoGenericParam *gparam =  t->data.generic_param;
+                               if (gparam->num < count) {
+                                       m->signature->params [i] = mono_metadata_type_dup (image, m->signature->params [i]);
+                                       m->signature->params [i]->data.generic_param = mono_generic_container_get_param (container, gparam->num);
+                               }
+
+                       }
+               }
+
+               if (klass->generic_container) {
+                       container->parent = klass->generic_container;
+                       container->context.class_inst = klass->generic_container->context.class_inst;
+               }
+               container->context.method_inst = mono_get_shared_generic_inst (container);
+       }
+
+       if (rmb->refs) {
+               MonoMethodWrapper *mw = (MonoMethodWrapper*)m;
+               int i;
+               void **data;
+
+               m->wrapper_type = MONO_WRAPPER_DYNAMIC_METHOD;
+
+               mw->method_data = data = image_g_new (image, gpointer, rmb->nrefs + 1);
+               data [0] = GUINT_TO_POINTER (rmb->nrefs);
+               for (i = 0; i < rmb->nrefs; ++i)
+                       data [i + 1] = rmb->refs [i];
+       }
+
+       method_aux = NULL;
+
+       /* Parameter info */
+       if (rmb->pinfo) {
+               if (!method_aux)
+                       method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
+               method_aux->param_names = image_g_new0 (image, char *, mono_method_signature (m)->param_count + 1);
+               for (i = 0; i <= m->signature->param_count; ++i) {
+                       MonoReflectionParamBuilder *pb;
+                       if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
+                               if ((i > 0) && (pb->attrs)) {
+                                       /* Make a copy since it might point to a shared type structure */
+                                       m->signature->params [i - 1] = mono_metadata_type_dup (klass->image, m->signature->params [i - 1]);
+                                       m->signature->params [i - 1]->attrs = pb->attrs;
+                               }
+
+                               if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
+                                       MonoDynamicImage *assembly;
+                                       guint32 idx, len;
+                                       MonoTypeEnum def_type;
+                                       char *p;
+                                       const char *p2;
+
+                                       if (!method_aux->param_defaults) {
+                                               method_aux->param_defaults = image_g_new0 (image, guint8*, m->signature->param_count + 1);
+                                               method_aux->param_default_types = image_g_new0 (image, guint32, m->signature->param_count + 1);
+                                       }
+                                       assembly = (MonoDynamicImage*)klass->image;
+                                       idx = mono_dynimage_encode_constant (assembly, pb->def_value, &def_type);
+                                       /* Copy the data from the blob since it might get realloc-ed */
+                                       p = assembly->blob.data + idx;
+                                       len = mono_metadata_decode_blob_size (p, &p2);
+                                       len += p2 - p;
+                                       method_aux->param_defaults [i] = (uint8_t *)image_g_malloc (image, len);
+                                       method_aux->param_default_types [i] = def_type;
+                                       memcpy ((gpointer)method_aux->param_defaults [i], p, len);
+                               }
+
+                               if (pb->name) {
+                                       method_aux->param_names [i] = mono_string_to_utf8_image (image, pb->name, error);
+                                       mono_error_assert_ok (error);
+                               }
+                               if (pb->cattrs) {
+                                       if (!method_aux->param_cattr)
+                                               method_aux->param_cattr = image_g_new0 (image, MonoCustomAttrInfo*, m->signature->param_count + 1);
+                                       method_aux->param_cattr [i] = mono_custom_attrs_from_builders (image, klass->image, pb->cattrs);
+                               }
+                       }
+               }
+       }
+
+       /* Parameter marshalling */
+       specs = NULL;
+       if (rmb->pinfo)         
+               for (i = 0; i < mono_array_length (rmb->pinfo); ++i) {
+                       MonoReflectionParamBuilder *pb;
+                       if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
+                               if (pb->marshal_info) {
+                                       if (specs == NULL)
+                                               specs = image_g_new0 (image, MonoMarshalSpec*, sig->param_count + 1);
+                                       specs [pb->position] = 
+                                               mono_marshal_spec_from_builder (image, klass->image->assembly, pb->marshal_info, error);
+                                       if (!is_ok (error)) {
+                                               mono_loader_unlock ();
+                                               image_g_free (image, specs);
+                                               /* FIXME: if image is NULL, this leaks all the other stuff we alloc'd in this function */
+                                               return NULL;
+                                       }
+                               }
+                       }
+               }
+       if (specs != NULL) {
+               if (!method_aux)
+                       method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
+               method_aux->param_marshall = specs;
+       }
+
+       if (image_is_dynamic (klass->image) && method_aux)
+               g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
+
+       mono_loader_unlock ();
+
+       return m;
+}      
+
+static MonoMethod*
+ctorbuilder_to_mono_method (MonoClass *klass, MonoReflectionCtorBuilder* mb, MonoError *error)
+{
+       ReflectionMethodBuilder rmb;
+       MonoMethodSignature *sig;
+
+       mono_loader_lock ();
+       g_assert (klass->image != NULL);
+       sig = ctor_builder_to_signature (klass->image, mb, error);
+       mono_loader_unlock ();
+       return_val_if_nok (error, NULL);
+
+       if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
+               return NULL;
+
+       mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
+       return_val_if_nok (error, NULL);
+       mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
+
+       /* If we are in a generic class, we might be called multiple times from inflate_method */
+       if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save && !klass->generic_container) {
+               /* ilgen is no longer needed */
+               mb->ilgen = NULL;
+       }
+
+       return mb->mhandle;
+}
+
+static MonoMethod*
+methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilder* mb, MonoError *error)
+{
+       ReflectionMethodBuilder rmb;
+       MonoMethodSignature *sig;
+
+       mono_error_init (error);
+
+       mono_loader_lock ();
+       g_assert (klass->image != NULL);
+       sig = method_builder_to_signature (klass->image, mb, error);
+       mono_loader_unlock ();
+       return_val_if_nok (error, NULL);
+
+       if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
+               return NULL;
+
+       mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
+       return_val_if_nok (error, NULL);
+       mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
+
+       /* If we are in a generic class, we might be called multiple times from inflate_method */
+       if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save && !klass->generic_container) {
+               /* ilgen is no longer needed */
+               mb->ilgen = NULL;
+       }
+       return mb->mhandle;
+}
+
+static MonoClassField*
+fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder* fb, MonoError *error)
+{
+       MonoClassField *field;
+       MonoType *custom;
+
+       mono_error_init (error);
+
+       field = g_new0 (MonoClassField, 1);
+
+       field->name = mono_string_to_utf8_image (klass->image, fb->name, error);
+       mono_error_assert_ok (error);
+       if (fb->attrs || fb->modreq || fb->modopt) {
+               MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
+               if (!is_ok (error)) {
+                       g_free (field);
+                       return NULL;
+               }
+               field->type = mono_metadata_type_dup (NULL, type);
+               field->type->attrs = fb->attrs;
+
+               g_assert (image_is_dynamic (klass->image));
+               custom = add_custom_modifiers ((MonoDynamicImage*)klass->image, field->type, fb->modreq, fb->modopt, error);
+               g_free (field->type);
+               if (!is_ok (error)) {
+                       g_free (field);
+                       return NULL;
+               }
+               field->type = mono_metadata_type_dup (klass->image, custom);
+               g_free (custom);
+       } else {
+               field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
+               if (!is_ok (error)) {
+                       g_free (field);
+                       return NULL;
+               }
+       }
+       if (fb->offset != -1)
+               field->offset = fb->offset;
+       field->parent = klass;
+       mono_save_custom_attrs (klass->image, field, fb->cattrs);
+
+       // FIXME: Can't store fb->def_value/RVA, is it needed for field_on_insts ?
+
+       return field;
+}
+#endif
+
+#ifndef DISABLE_REFLECTION_EMIT
+
+static MonoMethod *
+inflate_mono_method (MonoClass *klass, MonoMethod *method, MonoObject *obj)
+{
+       MonoMethodInflated *imethod;
+       MonoGenericContext *context;
+       int i;
+
+       /*
+        * With generic code sharing the klass might not be inflated.
+        * This can happen because classes inflated with their own
+        * type arguments are "normalized" to the uninflated class.
+        */
+       if (!klass->generic_class)
+               return method;
+
+       context = mono_class_get_context (klass);
+
+       if (klass->method.count && klass->methods) {
+               /* Find the already created inflated method */
+               for (i = 0; i < klass->method.count; ++i) {
+                       g_assert (klass->methods [i]->is_inflated);
+                       if (((MonoMethodInflated*)klass->methods [i])->declaring == method)
+                               break;
+               }
+               g_assert (i < klass->method.count);
+               imethod = (MonoMethodInflated*)klass->methods [i];
+       } else {
+               MonoError error;
+               imethod = (MonoMethodInflated *) mono_class_inflate_generic_method_full_checked (method, klass, context, &error);
+               mono_error_assert_ok (&error);
+       }
+
+       if (method->is_generic && image_is_dynamic (method->klass->image)) {
+               MonoDynamicImage *image = (MonoDynamicImage*)method->klass->image;
+
+               mono_image_lock ((MonoImage*)image);
+               mono_g_hash_table_insert (image->generic_def_objects, imethod, obj);
+               mono_image_unlock ((MonoImage*)image);
+       }
+       return (MonoMethod *) imethod;
+}
+
+static MonoMethod *
+inflate_method (MonoReflectionType *type, MonoObject *obj, MonoError *error)
+{
+       MonoMethod *method;
+       MonoClass *gklass;
+
+       mono_error_init (error);
+
+       MonoClass *type_class = mono_object_class (type);
+
+       if (is_sre_generic_instance (type_class)) {
+               MonoReflectionGenericClass *mgc = (MonoReflectionGenericClass*)type;
+               MonoType *generic_type = mono_reflection_type_get_handle ((MonoReflectionType*)mgc->generic_type, error);
+               return_val_if_nok (error, NULL);
+               gklass = mono_class_from_mono_type (generic_type);
+       } else if (is_sre_type_builder (type_class)) {
+               MonoType *t = mono_reflection_type_get_handle (type, error);
+               return_val_if_nok (error, NULL);
+               gklass = mono_class_from_mono_type (t);
+       } else if (type->type) {
+               gklass = mono_class_from_mono_type (type->type);
+               gklass = mono_class_get_generic_type_definition (gklass);
+       } else {
+               g_error ("Can't handle type %s", mono_type_get_full_name (mono_object_class (type)));
+       }
+
+       if (!strcmp (obj->vtable->klass->name, "MethodBuilder"))
+               if (((MonoReflectionMethodBuilder*)obj)->mhandle)
+                       method = ((MonoReflectionMethodBuilder*)obj)->mhandle;
+               else {
+                       method = methodbuilder_to_mono_method (gklass, (MonoReflectionMethodBuilder *) obj, error);
+                       if (!method)
+                               return NULL;
+               }
+       else if (!strcmp (obj->vtable->klass->name, "ConstructorBuilder")) {
+               method = ctorbuilder_to_mono_method (gklass, (MonoReflectionCtorBuilder *) obj, error);
+               if (!method)
+                       return NULL;
+       } else if (!strcmp (obj->vtable->klass->name, "MonoMethod") || !strcmp (obj->vtable->klass->name, "MonoCMethod"))
+               method = ((MonoReflectionMethod *) obj)->method;
+       else {
+               method = NULL; /* prevent compiler warning */
+               g_error ("can't handle type %s", obj->vtable->klass->name);
+       }
+
+       MonoType *t = mono_reflection_type_get_handle (type, error);
+       return_val_if_nok (error, NULL);
+       return inflate_mono_method (mono_class_from_mono_type (t), method, obj);
+}
+
+static void
+reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoError *error)
+{
+       MonoGenericClass *gclass;
+       MonoClass *klass, *gklass;
+       MonoType *gtype;
+
+       mono_error_init (error);
+
+       gtype = mono_reflection_type_get_handle ((MonoReflectionType*)type, error);
+       return_if_nok (error);
+       klass = mono_class_from_mono_type (gtype);
+       g_assert (gtype->type == MONO_TYPE_GENERICINST);
+       gclass = gtype->data.generic_class;
+
+       if (!gclass->is_dynamic)
+               return;
+
+       gklass = gclass->container_class;
+       mono_class_init (gklass);
+
+       /* Mark this as needing synchronization with its generic container */
+       gclass->need_sync = TRUE;
+}
+
+void
+mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields)
+{
+       MonoError error;
+       reflection_generic_class_initialize (type, &error);
+       mono_error_set_pending_exception (&error);
+}
+
+/**
+ * fix_partial_generic_class:
+ * @klass: a generic instantiation MonoClass
+ * @error: set on error
+ *
+ * Assumes that the generic container of @klass has its vtable
+ * initialized, and updates the parent class, interfaces, methods and
+ * fields of @klass by inflating the types using the generic context.
+ *
+ * On success returns TRUE, on failure returns FALSE and sets @error.
+ *
+ */
+static gboolean
+fix_partial_generic_class (MonoClass *klass, MonoError *error)
+{
+       MonoClass *gklass = klass->generic_class->container_class;
+       int i;
+
+       mono_error_init (error);
+
+       if (klass->wastypebuilder)
+               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);
+               if (mono_error_ok (error)) {
+                       MonoClass *parent = mono_class_from_mono_type (parent_type);
+                       mono_metadata_free_type (parent_type);
+                       if (parent != klass->parent) {
+                               /*fool mono_class_setup_parent*/
+                               klass->supertypes = NULL;
+                               mono_class_setup_parent (klass, parent);
+                       }
+               } else {
+                       if (gklass->wastypebuilder)
+                               klass->wastypebuilder = TRUE;
+                       return FALSE;
+               }
+       }
+
+       if (!klass->generic_class->need_sync)
+               return TRUE;
+
+       if (klass->method.count != gklass->method.count) {
+               klass->method.count = gklass->method.count;
+               klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * (klass->method.count + 1));
+
+               for (i = 0; i < klass->method.count; i++) {
+                       klass->methods [i] = mono_class_inflate_generic_method_full_checked (
+                               gklass->methods [i], klass, mono_class_get_context (klass), error);
+                       mono_error_assert_ok (error);
+               }
+       }
+
+       if (klass->interface_count && klass->interface_count != gklass->interface_count) {
+               klass->interface_count = gklass->interface_count;
+               klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * gklass->interface_count);
+               klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
+
+               for (i = 0; i < gklass->interface_count; ++i) {
+                       MonoType *iface_type = mono_class_inflate_generic_type_checked (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass), error);
+                       return_val_if_nok (error, FALSE);
+
+                       klass->interfaces [i] = mono_class_from_mono_type (iface_type);
+                       mono_metadata_free_type (iface_type);
+
+                       if (!ensure_runtime_vtable (klass->interfaces [i], error))
+                               return FALSE;
+               }
+               klass->interfaces_inited = 1;
+       }
+
+       if (klass->field.count != gklass->field.count) {
+               klass->field.count = gklass->field.count;
+               klass->fields = image_g_new0 (klass->image, MonoClassField, klass->field.count);
+
+               for (i = 0; i < klass->field.count; i++) {
+                       klass->fields [i] = gklass->fields [i];
+                       klass->fields [i].parent = klass;
+                       klass->fields [i].type = mono_class_inflate_generic_type_checked (gklass->fields [i].type, mono_class_get_context (klass), error);
+                       return_val_if_nok (error, FALSE);
+               }
+       }
+
+       /*We can only finish with this klass once it's parent has as well*/
+       if (gklass->wastypebuilder)
+               klass->wastypebuilder = TRUE;
+       return TRUE;
+}
+
+/**
+ * ensure_generic_class_runtime_vtable:
+ * @klass a generic class
+ * @error set on error
+ *
+ * Ensures that the generic container of @klass has a vtable and
+ * returns TRUE on success.  On error returns FALSE and sets @error.
+ */
+static gboolean
+ensure_generic_class_runtime_vtable (MonoClass *klass, MonoError *error)
+{
+       MonoClass *gklass = klass->generic_class->container_class;
+
+       mono_error_init (error);
+
+       if (!ensure_runtime_vtable (gklass, error))
+               return FALSE;
+
+       return fix_partial_generic_class (klass, error);
+}
+
+/**
+ * ensure_runtime_vtable:
+ * @klass the class
+ * @error set on error
+ *
+ * Ensures that @klass has a vtable and returns TRUE on success. On
+ * error returns FALSE and sets @error.
+ */
+static gboolean
+ensure_runtime_vtable (MonoClass *klass, MonoError *error)
+{
+       MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
+       int i, num, j;
+
+       mono_error_init (error);
+
+       if (!image_is_dynamic (klass->image) || (!tb && !klass->generic_class) || klass->wastypebuilder)
+               return TRUE;
+       if (klass->parent)
+               if (!ensure_runtime_vtable (klass->parent, error))
+                       return FALSE;
+
+       if (tb) {
+               num = tb->ctors? mono_array_length (tb->ctors): 0;
+               num += tb->num_methods;
+               klass->method.count = num;
+               klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * num);
+               num = tb->ctors? mono_array_length (tb->ctors): 0;
+               for (i = 0; i < num; ++i) {
+                       MonoMethod *ctor = ctorbuilder_to_mono_method (klass, mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i), error);
+                       if (!ctor)
+                               return FALSE;
+                       klass->methods [i] = ctor;
+               }
+               num = tb->num_methods;
+               j = i;
+               for (i = 0; i < num; ++i) {
+                       MonoMethod *meth = methodbuilder_to_mono_method (klass, mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), error);
+                       if (!meth)
+                               return FALSE;
+                       klass->methods [j++] = meth;
+               }
+       
+               if (tb->interfaces) {
+                       klass->interface_count = mono_array_length (tb->interfaces);
+                       klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
+                       for (i = 0; i < klass->interface_count; ++i) {
+                               MonoType *iface = mono_type_array_get_and_resolve (tb->interfaces, i, error);
+                               return_val_if_nok (error, FALSE);
+                               klass->interfaces [i] = mono_class_from_mono_type (iface);
+                               if (!ensure_runtime_vtable (klass->interfaces [i], error))
+                                       return FALSE;
+                       }
+                       klass->interfaces_inited = 1;
+               }
+       } else if (klass->generic_class){
+               if (!ensure_generic_class_runtime_vtable (klass, error)) {
+                       mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+                       return FALSE;
+               }
+       }
+
+       if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
+               int slot_num = 0;
+               for (i = 0; i < klass->method.count; ++i) {
+                       MonoMethod *im = klass->methods [i];
+                       if (!(im->flags & METHOD_ATTRIBUTE_STATIC))
+                               im->slot = slot_num++;
+               }
+               
+               klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
+               mono_class_setup_interface_offsets (klass);
+               mono_class_setup_interface_id (klass);
+       }
+
+       /*
+        * The generic vtable is needed even if image->run is not set since some
+        * runtime code like ves_icall_Type_GetMethodsByName depends on 
+        * method->slot being defined.
+        */
+
+       /* 
+        * tb->methods could not be freed since it is used for determining 
+        * overrides during dynamic vtable construction.
+        */
+
+       return TRUE;
+}
+
+static MonoMethod*
+mono_reflection_method_get_handle (MonoObject *method, MonoError *error)
+{
+       mono_error_init (error);
+       MonoClass *klass = mono_object_class (method);
+       if (is_sr_mono_method (klass) || is_sr_mono_generic_method (klass)) {
+               MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
+               return sr_method->method;
+       }
+       if (is_sre_method_builder (klass)) {
+               MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)method;
+               return mb->mhandle;
+       }
+       if (mono_is_sre_method_on_tb_inst (klass)) {
+               MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)method;
+               MonoMethod *result;
+               /*FIXME move this to a proper method and unify with resolve_object*/
+               if (m->method_args) {
+                       result = mono_reflection_method_on_tb_inst_get_handle (m, error);
+               } else {
+                       MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
+                       return_val_if_nok (error, NULL);
+                       MonoClass *inflated_klass = mono_class_from_mono_type (type);
+                       MonoMethod *mono_method;
+
+                       if (is_sre_method_builder (mono_object_class (m->mb)))
+                               mono_method = ((MonoReflectionMethodBuilder *)m->mb)->mhandle;
+                       else if (is_sr_mono_method (mono_object_class (m->mb)))
+                               mono_method = ((MonoReflectionMethod *)m->mb)->method;
+                       else
+                               g_error ("resolve_object:: can't handle a MTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (m->mb)));
+
+                       result = inflate_mono_method (inflated_klass, mono_method, (MonoObject*)m->mb);
+               }
+               return result;
+       }
+
+       g_error ("Can't handle methods of type %s:%s", klass->name_space, klass->name);
+       return NULL;
+}
+
+void
+mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
+{
+       MonoReflectionTypeBuilder *tb;
+       int i, j, onum;
+       MonoReflectionMethod *m;
+
+       mono_error_init (error);
+       *overrides = NULL;
+       *num_overrides = 0;
+
+       g_assert (image_is_dynamic (klass->image));
+
+       if (!mono_class_get_ref_info (klass))
+               return;
+
+       g_assert (strcmp (((MonoObject*)mono_class_get_ref_info (klass))->vtable->klass->name, "TypeBuilder") == 0);
+
+       tb = (MonoReflectionTypeBuilder*)mono_class_get_ref_info (klass);
+
+       onum = 0;
+       if (tb->methods) {
+               for (i = 0; i < tb->num_methods; ++i) {
+                       MonoReflectionMethodBuilder *mb = 
+                               mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
+                       if (mb->override_methods)
+                               onum += mono_array_length (mb->override_methods);
+               }
+       }
+
+       if (onum) {
+               *overrides = g_new0 (MonoMethod*, onum * 2);
+
+               onum = 0;
+               for (i = 0; i < tb->num_methods; ++i) {
+                       MonoReflectionMethodBuilder *mb = 
+                               mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
+                       if (mb->override_methods) {
+                               for (j = 0; j < mono_array_length (mb->override_methods); ++j) {
+                                       m = mono_array_get (mb->override_methods, MonoReflectionMethod*, j);
+
+                                       (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject*)m, error);
+                                       return_if_nok (error);
+                                       (*overrides) [onum * 2 + 1] = mb->mhandle;
+
+                                       g_assert (mb->mhandle);
+
+                                       onum ++;
+                               }
+                       }
+               }
+       }
+
+       *num_overrides = onum;
+}
+
+static void
+typebuilder_setup_fields (MonoClass *klass, MonoError *error)
+{
+       MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
+       MonoReflectionFieldBuilder *fb;
+       MonoClassField *field;
+       MonoImage *image = klass->image;
+       const char *p, *p2;
+       int i;
+       guint32 len, idx, real_size = 0;
+
+       klass->field.count = tb->num_fields;
+       klass->field.first = 0;
+
+       mono_error_init (error);
+
+       if (tb->class_size) {
+               if ((tb->packing_size & 0xffffff00) != 0) {
+                       char *err_msg = g_strdup_printf ("Could not load struct '%s' with packing size %d >= 256", klass->name, tb->packing_size);
+                       mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
+                       return;
+               }
+               klass->packing_size = tb->packing_size;
+               real_size = klass->instance_size + tb->class_size;
+       }
+
+       if (!klass->field.count) {
+               klass->instance_size = MAX (klass->instance_size, real_size);
+               return;
+       }
+       
+       klass->fields = image_g_new0 (image, MonoClassField, klass->field.count);
+       mono_class_alloc_ext (klass);
+       klass->ext->field_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->field.count);
+       /*
+       This is, guess what, a hack.
+       The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
+       On the static path no field class is resolved, only types are built. This is the right thing to do
+       but we suck.
+       Setting size_inited is harmless because we're doing the same job as mono_class_setup_fields anyway.
+       */
+       klass->size_inited = 1;
+
+       for (i = 0; i < klass->field.count; ++i) {
+               MonoArray *rva_data;
+               fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
+               field = &klass->fields [i];
+               field->name = mono_string_to_utf8_image (image, fb->name, error);
+               if (!mono_error_ok (error))
+                       return;
+               if (fb->attrs) {
+                       MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
+                       return_if_nok (error);
+                       field->type = mono_metadata_type_dup (klass->image, type);
+                       field->type->attrs = fb->attrs;
+               } else {
+                       field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
+                       return_if_nok (error);
+               }
+
+               if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
+                       char *base = mono_array_addr (rva_data, char, 0);
+                       size_t size = mono_array_length (rva_data);
+                       char *data = (char *)mono_image_alloc (klass->image, size);
+                       memcpy (data, base, size);
+                       klass->ext->field_def_values [i].data = data;
+               }
+               if (fb->offset != -1)
+                       field->offset = fb->offset;
+               field->parent = klass;
+               fb->handle = field;
+               mono_save_custom_attrs (klass->image, field, fb->cattrs);
+
+               if (klass->enumtype && !(field->type->attrs & FIELD_ATTRIBUTE_STATIC)) {
+                       klass->cast_class = klass->element_class = mono_class_from_mono_type (field->type);
+               }
+               if (fb->def_value) {
+                       MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
+                       field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
+                       idx = mono_dynimage_encode_constant (assembly, fb->def_value, &klass->ext->field_def_values [i].def_type);
+                       /* Copy the data from the blob since it might get realloc-ed */
+                       p = assembly->blob.data + idx;
+                       len = mono_metadata_decode_blob_size (p, &p2);
+                       len += p2 - p;
+                       klass->ext->field_def_values [i].data = (const char *)mono_image_alloc (image, len);
+                       memcpy ((gpointer)klass->ext->field_def_values [i].data, p, len);
+               }
+       }
+
+       klass->instance_size = MAX (klass->instance_size, real_size);
+       mono_class_layout_fields (klass, klass->instance_size);
+}
+
+static void
+typebuilder_setup_properties (MonoClass *klass, MonoError *error)
+{
+       MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
+       MonoReflectionPropertyBuilder *pb;
+       MonoImage *image = klass->image;
+       MonoProperty *properties;
+       int i;
+
+       mono_error_init (error);
+
+       if (!klass->ext)
+               klass->ext = image_g_new0 (image, MonoClassExt, 1);
+
+       klass->ext->property.count = tb->properties ? mono_array_length (tb->properties) : 0;
+       klass->ext->property.first = 0;
+
+       properties = image_g_new0 (image, MonoProperty, klass->ext->property.count);
+       klass->ext->properties = properties;
+       for (i = 0; i < klass->ext->property.count; ++i) {
+               pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
+               properties [i].parent = klass;
+               properties [i].attrs = pb->attrs;
+               properties [i].name = mono_string_to_utf8_image (image, pb->name, error);
+               if (!mono_error_ok (error))
+                       return;
+               if (pb->get_method)
+                       properties [i].get = pb->get_method->mhandle;
+               if (pb->set_method)
+                       properties [i].set = pb->set_method->mhandle;
+
+               mono_save_custom_attrs (klass->image, &properties [i], pb->cattrs);
+               if (pb->def_value) {
+                       guint32 len, idx;
+                       const char *p, *p2;
+                       MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
+                       if (!klass->ext->prop_def_values)
+                               klass->ext->prop_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->ext->property.count);
+                       properties [i].attrs |= PROPERTY_ATTRIBUTE_HAS_DEFAULT;
+                       idx = mono_dynimage_encode_constant (assembly, pb->def_value, &klass->ext->prop_def_values [i].def_type);
+                       /* Copy the data from the blob since it might get realloc-ed */
+                       p = assembly->blob.data + idx;
+                       len = mono_metadata_decode_blob_size (p, &p2);
+                       len += p2 - p;
+                       klass->ext->prop_def_values [i].data = (const char *)mono_image_alloc (image, len);
+                       memcpy ((gpointer)klass->ext->prop_def_values [i].data, p, len);
+               }
+       }
+}
+
+static MonoReflectionEvent *
+reflection_event_builder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb, MonoError *error)
+{
+       mono_error_init (error);
+
+       MonoEvent *event = g_new0 (MonoEvent, 1);
+       MonoClass *klass;
+
+       MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
+       if (!is_ok (error)) {
+               g_free (event);
+               return NULL;
+       }
+       klass = mono_class_from_mono_type (type);
+
+       event->parent = klass;
+       event->attrs = eb->attrs;
+       event->name = mono_string_to_utf8_checked (eb->name, error);
+       if (!is_ok (error)) {
+               g_free (event);
+               return NULL;
+       }
+       if (eb->add_method)
+               event->add = eb->add_method->mhandle;
+       if (eb->remove_method)
+               event->remove = eb->remove_method->mhandle;
+       if (eb->raise_method)
+               event->raise = eb->raise_method->mhandle;
+
+#ifndef MONO_SMALL_CONFIG
+       if (eb->other_methods) {
+               int j;
+               event->other = g_new0 (MonoMethod*, mono_array_length (eb->other_methods) + 1);
+               for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
+                       MonoReflectionMethodBuilder *mb = 
+                               mono_array_get (eb->other_methods,
+                                               MonoReflectionMethodBuilder*, j);
+                       event->other [j] = mb->mhandle;
+               }
+       }
+#endif
+
+       MonoReflectionEvent *ev_obj = mono_event_get_object_checked (mono_object_domain (tb), klass, event, error);
+       if (!is_ok (error)) {
+#ifndef MONO_SMALL_CONFIG
+               g_free (event->other);
+#endif
+               g_free (event);
+               return NULL;
+       }
+       return ev_obj;
+}
+
+MonoReflectionEvent *
+ves_icall_TypeBuilder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb)
+{
+       MonoError error;
+       MonoReflectionEvent *result = reflection_event_builder_get_event_info (tb, eb, &error);
+       mono_error_set_pending_exception (&error);
+       return result;
+}
+
+static void
+typebuilder_setup_events (MonoClass *klass, MonoError *error)
+{
+       MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
+       MonoReflectionEventBuilder *eb;
+       MonoImage *image = klass->image;
+       MonoEvent *events;
+       int i;
+
+       mono_error_init (error);
+
+       if (!klass->ext)
+               klass->ext = image_g_new0 (image, MonoClassExt, 1);
+
+       klass->ext->event.count = tb->events ? mono_array_length (tb->events) : 0;
+       klass->ext->event.first = 0;
+
+       events = image_g_new0 (image, MonoEvent, klass->ext->event.count);
+       klass->ext->events = events;
+       for (i = 0; i < klass->ext->event.count; ++i) {
+               eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
+               events [i].parent = klass;
+               events [i].attrs = eb->attrs;
+               events [i].name = mono_string_to_utf8_image (image, eb->name, error);
+               if (!mono_error_ok (error))
+                       return;
+               if (eb->add_method)
+                       events [i].add = eb->add_method->mhandle;
+               if (eb->remove_method)
+                       events [i].remove = eb->remove_method->mhandle;
+               if (eb->raise_method)
+                       events [i].raise = eb->raise_method->mhandle;
+
+#ifndef MONO_SMALL_CONFIG
+               if (eb->other_methods) {
+                       int j;
+                       events [i].other = image_g_new0 (image, MonoMethod*, mono_array_length (eb->other_methods) + 1);
+                       for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
+                               MonoReflectionMethodBuilder *mb = 
+                                       mono_array_get (eb->other_methods,
+                                                                       MonoReflectionMethodBuilder*, j);
+                               events [i].other [j] = mb->mhandle;
+                       }
+               }
+#endif
+               mono_save_custom_attrs (klass->image, &events [i], eb->cattrs);
+       }
+}
+
+struct remove_instantiations_user_data
+{
+       MonoClass *klass;
+       MonoError *error;
+};
+
+static gboolean
+remove_instantiations_of_and_ensure_contents (gpointer key,
+                                                 gpointer value,
+                                                 gpointer user_data)
+{
+       struct remove_instantiations_user_data *data = (struct remove_instantiations_user_data*)user_data;
+       MonoType *type = (MonoType*)key;
+       MonoClass *klass = data->klass;
+       gboolean already_failed = !is_ok (data->error);
+       MonoError lerror;
+       MonoError *error = already_failed ? &lerror : data->error;
+
+       if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass)) {
+               MonoClass *inst_klass = mono_class_from_mono_type (type);
+               //Ensure it's safe to use it.
+               if (!fix_partial_generic_class (inst_klass, error)) {
+                       mono_class_set_failure (inst_klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+                       // Marked the class with failure, but since some other instantiation already failed,
+                       // just report that one, and swallow the error from this one.
+                       if (already_failed)
+                               mono_error_cleanup (error);
+               }
+               return TRUE;
+       } else
+               return FALSE;
+}
+
+MonoReflectionType*
+ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
+{
+       MonoError error;
+       MonoClass *klass;
+       MonoDomain* domain;
+       MonoReflectionType* res;
+       int i;
+
+       mono_error_init (&error);
+
+       domain = mono_object_domain (tb);
+       klass = mono_class_from_mono_type (tb->type.type);
+
+       mono_save_custom_attrs (klass->image, klass, tb->cattrs);
+
+       /* 
+        * we need to lock the domain because the lock will be taken inside
+        * So, we need to keep the locking order correct.
+        */
+       mono_loader_lock ();
+       mono_domain_lock (domain);
+       if (klass->wastypebuilder) {
+               mono_domain_unlock (domain);
+               mono_loader_unlock ();
+
+               res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
+               mono_error_set_pending_exception (&error);
+
+               return res;
+       }
+       /*
+        * Fields to set in klass:
+        * the various flags: delegate/unicode/contextbound etc.
+        */
+       klass->flags = tb->attrs;
+       klass->has_cctor = 1;
+
+       mono_class_setup_parent (klass, klass->parent);
+       /* fool mono_class_setup_supertypes */
+       klass->supertypes = NULL;
+       mono_class_setup_supertypes (klass);
+       mono_class_setup_mono_type (klass);
+
+#if 0
+       if (!((MonoDynamicImage*)klass->image)->run) {
+               if (klass->generic_container) {
+                       /* FIXME: The code below can't handle generic classes */
+                       klass->wastypebuilder = TRUE;
+                       mono_loader_unlock ();
+                       mono_domain_unlock (domain);
+
+                       res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
+                       mono_error_set_pending_exception (&error);
+
+                       return res;
+               }
+       }
+#endif
+
+       /* enums are done right away */
+       if (!klass->enumtype)
+               if (!ensure_runtime_vtable (klass, &error))
+                       goto failure;
+
+       if (tb->subtypes) {
+               for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
+                       MonoReflectionTypeBuilder *subtb = mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i);
+                       mono_class_alloc_ext (klass);
+                       MonoType *subtype = mono_reflection_type_get_handle ((MonoReflectionType*)subtb, &error);
+                       if (!is_ok (&error)) goto failure;
+                       klass->ext->nested_classes = g_list_prepend_image (klass->image, klass->ext->nested_classes, mono_class_from_mono_type (subtype));
+               }
+       }
+
+       klass->nested_classes_inited = TRUE;
+
+       /* fields and object layout */
+       if (klass->parent) {
+               if (!klass->parent->size_inited)
+                       mono_class_init (klass->parent);
+               klass->instance_size = klass->parent->instance_size;
+               klass->sizes.class_size = 0;
+               klass->min_align = klass->parent->min_align;
+               /* if the type has no fields we won't call the field_setup
+                * routine which sets up klass->has_references.
+                */
+               klass->has_references |= klass->parent->has_references;
+       } else {
+               klass->instance_size = sizeof (MonoObject);
+               klass->min_align = 1;
+       }
+
+       /* FIXME: handle packing_size and instance_size */
+       typebuilder_setup_fields (klass, &error);
+       if (!mono_error_ok (&error))
+               goto failure;
+       typebuilder_setup_properties (klass, &error);
+       if (!mono_error_ok (&error))
+               goto failure;
+
+       typebuilder_setup_events (klass, &error);
+       if (!mono_error_ok (&error))
+               goto failure;
+
+       klass->wastypebuilder = TRUE;
+
+       /* 
+        * If we are a generic TypeBuilder, there might be instantiations in the type cache
+        * which have type System.Reflection.MonoGenericClass, but after the type is created, 
+        * we want to return normal System.MonoType objects, so clear these out from the cache.
+        *
+        * Together with this we must ensure the contents of all instances to match the created type.
+        */
+       if (domain->type_hash && klass->generic_container) {
+               struct remove_instantiations_user_data data;
+               data.klass = klass;
+               data.error = &error;
+               mono_error_assert_ok (&error);
+               mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of_and_ensure_contents, &data);
+               if (!is_ok (&error))
+                       goto failure;
+       }
+
+       mono_domain_unlock (domain);
+       mono_loader_unlock ();
+
+       if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
+               mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+               mono_error_set_type_load_class (&error, klass, "Not a valid enumeration");
+               goto failure_unlocked;
+       }
+
+       res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
+       if (!is_ok (&error))
+               goto failure_unlocked;
+
+       g_assert (res != (MonoReflectionType*)tb);
+
+       return res;
+
+failure:
+       mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+       klass->wastypebuilder = TRUE;
+       mono_domain_unlock (domain);
+       mono_loader_unlock ();
+failure_unlocked:
+       mono_error_set_pending_exception (&error);
+       return NULL;
+}
+
+static gboolean
+reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam, MonoError *error)
+{
+       MonoGenericParamFull *param;
+       MonoImage *image;
+       MonoClass *pklass;
+
+       mono_error_init (error);
+
+       image = &gparam->tbuilder->module->dynamic_image->image;
+
+       param = mono_image_new0 (image, MonoGenericParamFull, 1);
+
+       param->info.name = mono_string_to_utf8_image (image, gparam->name, error);
+       mono_error_assert_ok (error);
+       param->param.num = gparam->index;
+
+       if (gparam->mbuilder) {
+               if (!gparam->mbuilder->generic_container) {
+                       MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->mbuilder->type, error);
+                       return_val_if_nok (error, FALSE);
+
+                       MonoClass *klass = mono_class_from_mono_type (tb);
+                       gparam->mbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
+                       gparam->mbuilder->generic_container->is_method = TRUE;
+                       /* 
+                        * Cannot set owner.method, since the MonoMethod is not created yet.
+                        * Set the image field instead, so type_in_image () works.
+                        */
+                       gparam->mbuilder->generic_container->is_anonymous = TRUE;
+                       gparam->mbuilder->generic_container->owner.image = klass->image;
+               }
+               param->param.owner = gparam->mbuilder->generic_container;
+       } else if (gparam->tbuilder) {
+               if (!gparam->tbuilder->generic_container) {
+                       MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->tbuilder, error);
+                       return_val_if_nok (error, FALSE);
+                       MonoClass *klass = mono_class_from_mono_type (tb);
+                       gparam->tbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
+                       gparam->tbuilder->generic_container->owner.klass = klass;
+               }
+               param->param.owner = gparam->tbuilder->generic_container;
+       }
+
+       pklass = mono_class_from_generic_parameter_internal ((MonoGenericParam *) param);
+
+       gparam->type.type = &pklass->byval_arg;
+
+       mono_class_set_ref_info (pklass, gparam);
+       mono_image_append_class_to_reflection_info_set (pklass);
+
+       return TRUE;
+}
+
+void
+ves_icall_GenericTypeParameterBuilder_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
+{
+       MonoError error;
+       (void) reflection_initialize_generic_parameter (gparam, &error);
+       mono_error_set_pending_exception (&error);
+}
+
+
+typedef struct {
+       MonoMethod *handle;
+       MonoDomain *domain;
+} DynamicMethodReleaseData;
+
+/*
+ * The runtime automatically clean up those after finalization.
+*/     
+static MonoReferenceQueue *dynamic_method_queue;
+
+static void
+free_dynamic_method (void *dynamic_method)
+{
+       DynamicMethodReleaseData *data = (DynamicMethodReleaseData *)dynamic_method;
+       MonoDomain *domain = data->domain;
+       MonoMethod *method = data->handle;
+       guint32 dis_link;
+
+       mono_domain_lock (domain);
+       dis_link = (guint32)(size_t)g_hash_table_lookup (domain->method_to_dyn_method, method);
+       g_hash_table_remove (domain->method_to_dyn_method, method);
+       mono_domain_unlock (domain);
+       g_assert (dis_link);
+       mono_gchandle_free (dis_link);
+
+       mono_runtime_free_method (domain, method);
+       g_free (data);
+}
+
+static gboolean
+reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb, MonoError *error)
+{
+       MonoReferenceQueue *queue;
+       MonoMethod *handle;
+       DynamicMethodReleaseData *release_data;
+       ReflectionMethodBuilder rmb;
+       MonoMethodSignature *sig;
+       MonoClass *klass;
+       MonoDomain *domain;
+       GSList *l;
+       int i;
+
+       mono_error_init (error);
+
+       if (mono_runtime_is_shutting_down ()) {
+               mono_error_set_generic_error (error, "System", "InvalidOperationException", "");
+               return FALSE;
+       }
+
+       if (!(queue = dynamic_method_queue)) {
+               mono_loader_lock ();
+               if (!(queue = dynamic_method_queue))
+                       queue = dynamic_method_queue = mono_gc_reference_queue_new (free_dynamic_method);
+               mono_loader_unlock ();
+       }
+
+       sig = dynamic_method_to_signature (mb, error);
+       return_val_if_nok (error, FALSE);
+
+       reflection_methodbuilder_from_dynamic_method (&rmb, mb);
+
+       /*
+        * Resolve references.
+        */
+       /* 
+        * Every second entry in the refs array is reserved for storing handle_class,
+        * which is needed by the ldtoken implementation in the JIT.
+        */
+       rmb.nrefs = mb->nrefs;
+       rmb.refs = g_new0 (gpointer, mb->nrefs + 1);
+       for (i = 0; i < mb->nrefs; i += 2) {
+               MonoClass *handle_class;
+               gpointer ref;
+               MonoObject *obj = mono_array_get (mb->refs, MonoObject*, i);
+
+               if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
+                       MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
+                       /*
+                        * The referenced DynamicMethod should already be created by the managed
+                        * code, except in the case of circular references. In that case, we store
+                        * method in the refs array, and fix it up later when the referenced 
+                        * DynamicMethod is created.
+                        */
+                       if (method->mhandle) {
+                               ref = method->mhandle;
+                       } else {
+                               /* FIXME: GC object stored in unmanaged memory */
+                               ref = method;
+
+                               /* FIXME: GC object stored in unmanaged memory */
+                               method->referenced_by = g_slist_append (method->referenced_by, mb);
+                       }
+                       handle_class = mono_defaults.methodhandle_class;
+               } else {
+                       MonoException *ex = NULL;
+                       ref = mono_reflection_resolve_object (mb->module->image, obj, &handle_class, NULL, error);
+                       if (!is_ok  (error)) {
+                               g_free (rmb.refs);
+                               return FALSE;
+                       }
+                       if (!ref)
+                               ex = mono_get_exception_type_load (NULL, NULL);
+                       else if (mono_security_core_clr_enabled ())
+                               ex = mono_security_core_clr_ensure_dynamic_method_resolved_object (ref, handle_class);
+
+                       if (ex) {
+                               g_free (rmb.refs);
+                               mono_error_set_exception_instance (error, ex);
+                               return FALSE;
+                       }
+               }
+
+               rmb.refs [i] = ref; /* FIXME: GC object stored in unmanaged memory (change also resolve_object() signature) */
+               rmb.refs [i + 1] = handle_class;
+       }               
+
+       if (mb->owner) {
+               MonoType *owner_type = mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner, error);
+               if (!is_ok (error)) {
+                       g_free (rmb.refs);
+                       return FALSE;
+               }
+               klass = mono_class_from_mono_type (owner_type);
+       } else {
+               klass = mono_defaults.object_class;
+       }
+
+       mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
+       g_free (rmb.refs);
+       return_val_if_nok (error, FALSE);
+
+       release_data = g_new (DynamicMethodReleaseData, 1);
+       release_data->handle = handle;
+       release_data->domain = mono_object_get_domain ((MonoObject*)mb);
+       if (!mono_gc_reference_queue_add (queue, (MonoObject*)mb, release_data))
+               g_free (release_data);
+
+       /* Fix up refs entries pointing at us */
+       for (l = mb->referenced_by; l; l = l->next) {
+               MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)l->data;
+               MonoMethodWrapper *wrapper = (MonoMethodWrapper*)method->mhandle;
+               gpointer *data;
+               
+               g_assert (method->mhandle);
+
+               data = (gpointer*)wrapper->method_data;
+               for (i = 0; i < GPOINTER_TO_UINT (data [0]); i += 2) {
+                       if ((data [i + 1] == mb) && (data [i + 1 + 1] == mono_defaults.methodhandle_class))
+                               data [i + 1] = mb->mhandle;
+               }
+       }
+       g_slist_free (mb->referenced_by);
+
+       /* ilgen is no longer needed */
+       mb->ilgen = NULL;
+
+       domain = mono_domain_get ();
+       mono_domain_lock (domain);
+       if (!domain->method_to_dyn_method)
+               domain->method_to_dyn_method = g_hash_table_new (NULL, NULL);
+       g_hash_table_insert (domain->method_to_dyn_method, handle, (gpointer)(size_t)mono_gchandle_new_weakref ((MonoObject *)mb, TRUE));
+       mono_domain_unlock (domain);
+
+       return TRUE;
+}
+
+void
+ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
+{
+       MonoError error;
+       (void) reflection_create_dynamic_method (mb, &error);
+       mono_error_set_pending_exception (&error);
+}
+
+#endif /* DISABLE_REFLECTION_EMIT */
+
+MonoMethodSignature *
+mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token, MonoError *error)
+{
+       MonoMethodSignature *sig;
+       g_assert (image_is_dynamic (image));
+
+       mono_error_init (error);
+
+       sig = (MonoMethodSignature *)g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
+       if (sig)
+               return sig;
+
+       return mono_method_signature_checked (method, error);
+}
+
+#ifndef DISABLE_REFLECTION_EMIT
+
+/*
+ * ensure_complete_type:
+ *
+ *   Ensure that KLASS is completed if it is a dynamic type, or references
+ * dynamic types.
+ */
+static void
+ensure_complete_type (MonoClass *klass, MonoError *error)
+{
+       mono_error_init (error);
+
+       if (image_is_dynamic (klass->image) && !klass->wastypebuilder && mono_class_get_ref_info (klass)) {
+               MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
+
+               mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
+               return_if_nok (error);
+
+               // Asserting here could break a lot of code
+               //g_assert (klass->wastypebuilder);
+       }
+
+       if (klass->generic_class) {
+               MonoGenericInst *inst = klass->generic_class->context.class_inst;
+               int i;
+
+               for (i = 0; i < inst->type_argc; ++i) {
+                       ensure_complete_type (mono_class_from_mono_type (inst->type_argv [i]), error);
+                       return_if_nok (error);
+               }
+       }
+}
+
+gpointer
+mono_reflection_resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
+{
+       gpointer result = NULL;
+
+       mono_error_init (error);
+
+       if (strcmp (obj->vtable->klass->name, "String") == 0) {
+               result = mono_string_intern_checked ((MonoString*)obj, error);
+               return_val_if_nok (error, NULL);
+               *handle_class = mono_defaults.string_class;
+               g_assert (result);
+       } else if (strcmp (obj->vtable->klass->name, "RuntimeType") == 0) {
+               MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
+               return_val_if_nok (error, NULL);
+               MonoClass *mc = mono_class_from_mono_type (type);
+               if (!mono_class_init (mc)) {
+                       mono_error_set_for_class_failure (error, mc);
+                       return NULL;
+               }
+
+               if (context) {
+                       MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
+                       return_val_if_nok (error, NULL);
+
+                       result = mono_class_from_mono_type (inflated);
+                       mono_metadata_free_type (inflated);
+               } else {
+                       result = mono_class_from_mono_type (type);
+               }
+               *handle_class = mono_defaults.typehandle_class;
+               g_assert (result);
+       } else if (strcmp (obj->vtable->klass->name, "MonoMethod") == 0 ||
+                  strcmp (obj->vtable->klass->name, "MonoCMethod") == 0 ||
+                  strcmp (obj->vtable->klass->name, "MonoGenericCMethod") == 0 ||
+                  strcmp (obj->vtable->klass->name, "MonoGenericMethod") == 0) {
+               result = ((MonoReflectionMethod*)obj)->method;
+               if (context) {
+                       result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
+                       mono_error_assert_ok (error);
+               }
+               *handle_class = mono_defaults.methodhandle_class;
+               g_assert (result);
+       } else if (strcmp (obj->vtable->klass->name, "MethodBuilder") == 0) {
+               MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)obj;
+               result = mb->mhandle;
+               if (!result) {
+                       /* Type is not yet created */
+                       MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
+
+                       mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
+                       return_val_if_nok (error, NULL);
+
+                       /*
+                        * Hopefully this has been filled in by calling CreateType() on the
+                        * TypeBuilder.
+                        */
+                       /*
+                        * TODO: This won't work if the application finishes another 
+                        * TypeBuilder instance instead of this one.
+                        */
+                       result = mb->mhandle;
+               }
+               if (context) {
+                       result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
+                       mono_error_assert_ok (error);
+               }
+               *handle_class = mono_defaults.methodhandle_class;
+       } else if (strcmp (obj->vtable->klass->name, "ConstructorBuilder") == 0) {
+               MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder*)obj;
+
+               result = cb->mhandle;
+               if (!result) {
+                       MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)cb->type;
+
+                       mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
+                       return_val_if_nok (error, NULL);
+                       result = cb->mhandle;
+               }
+               if (context) {
+                       result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
+                       mono_error_assert_ok (error);
+               }
+               *handle_class = mono_defaults.methodhandle_class;
+       } else if (strcmp (obj->vtable->klass->name, "MonoField") == 0) {
+               MonoClassField *field = ((MonoReflectionField*)obj)->field;
+
+               ensure_complete_type (field->parent, error);
+               return_val_if_nok (error, NULL);
+
+               if (context) {
+                       MonoType *inflated = mono_class_inflate_generic_type_checked (&field->parent->byval_arg, context, error);
+                       return_val_if_nok (error, NULL);
+
+                       MonoClass *klass = mono_class_from_mono_type (inflated);
+                       MonoClassField *inflated_field;
+                       gpointer iter = NULL;
+                       mono_metadata_free_type (inflated);
+                       while ((inflated_field = mono_class_get_fields (klass, &iter))) {
+                               if (!strcmp (field->name, inflated_field->name))
+                                       break;
+                       }
+                       g_assert (inflated_field && !strcmp (field->name, inflated_field->name));
+                       result = inflated_field;
+               } else {
+                       result = field;
+               }
+               *handle_class = mono_defaults.fieldhandle_class;
+               g_assert (result);
+       } else if (strcmp (obj->vtable->klass->name, "FieldBuilder") == 0) {
+               MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder*)obj;
+               result = fb->handle;
+
+               if (!result) {
+                       MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)fb->typeb;
+
+                       mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
+                       return_val_if_nok (error, NULL);
+                       result = fb->handle;
+               }
+
+               if (fb->handle && fb->handle->parent->generic_container) {
+                       MonoClass *klass = fb->handle->parent;
+                       MonoType *type = mono_class_inflate_generic_type_checked (&klass->byval_arg, context, error);
+                       return_val_if_nok (error, NULL);
+
+                       MonoClass *inflated = mono_class_from_mono_type (type);
+
+                       result = mono_class_get_field_from_name (inflated, mono_field_get_name (fb->handle));
+                       g_assert (result);
+                       mono_metadata_free_type (type);
+               }
+               *handle_class = mono_defaults.fieldhandle_class;
+       } else if (strcmp (obj->vtable->klass->name, "TypeBuilder") == 0) {
+               MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
+               MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
+               return_val_if_nok (error, NULL);
+               MonoClass *klass;
+
+               klass = type->data.klass;
+               if (klass->wastypebuilder) {
+                       /* Already created */
+                       result = klass;
+               }
+               else {
+                       mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
+                       return_val_if_nok (error, NULL);
+                       result = type->data.klass;
+                       g_assert (result);
+               }
+               *handle_class = mono_defaults.typehandle_class;
+       } else if (strcmp (obj->vtable->klass->name, "SignatureHelper") == 0) {
+               MonoReflectionSigHelper *helper = (MonoReflectionSigHelper*)obj;
+               MonoMethodSignature *sig;
+               int nargs, i;
+
+               if (helper->arguments)
+                       nargs = mono_array_length (helper->arguments);
+               else
+                       nargs = 0;
+
+               sig = mono_metadata_signature_alloc (image, nargs);
+               sig->explicit_this = helper->call_conv & 64 ? 1 : 0;
+               sig->hasthis = helper->call_conv & 32 ? 1 : 0;
+
+               if (helper->unmanaged_call_conv) { /* unmanaged */
+                       sig->call_convention = helper->unmanaged_call_conv - 1;
+                       sig->pinvoke = TRUE;
+               } else if (helper->call_conv & 0x02) {
+                       sig->call_convention = MONO_CALL_VARARG;
+               } else {
+                       sig->call_convention = MONO_CALL_DEFAULT;
+               }
+
+               sig->param_count = nargs;
+               /* TODO: Copy type ? */
+               sig->ret = helper->return_type->type;
+               for (i = 0; i < nargs; ++i) {
+                       sig->params [i] = mono_type_array_get_and_resolve (helper->arguments, i, error);
+                       if (!is_ok (error)) {
+                               image_g_free (image, sig);
+                               return NULL;
+                       }
+               }
+
+               result = sig;
+               *handle_class = NULL;
+       } else if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
+               MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
+               /* Already created by the managed code */
+               g_assert (method->mhandle);
+               result = method->mhandle;
+               *handle_class = mono_defaults.methodhandle_class;
+       } else if (strcmp (obj->vtable->klass->name, "GenericTypeParameterBuilder") == 0) {
+               MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
+               return_val_if_nok (error, NULL);
+               type = mono_class_inflate_generic_type_checked (type, context, error);
+               return_val_if_nok (error, NULL);
+
+               result = mono_class_from_mono_type (type);
+               *handle_class = mono_defaults.typehandle_class;
+               g_assert (result);
+               mono_metadata_free_type (type);
+       } else if (strcmp (obj->vtable->klass->name, "MonoGenericClass") == 0) {
+               MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
+               return_val_if_nok (error, NULL);
+               type = mono_class_inflate_generic_type_checked (type, context, error);
+               return_val_if_nok (error, NULL);
+
+               result = mono_class_from_mono_type (type);
+               *handle_class = mono_defaults.typehandle_class;
+               g_assert (result);
+               mono_metadata_free_type (type);
+       } else if (strcmp (obj->vtable->klass->name, "FieldOnTypeBuilderInst") == 0) {
+               MonoReflectionFieldOnTypeBuilderInst *f = (MonoReflectionFieldOnTypeBuilderInst*)obj;
+               MonoClass *inflated;
+               MonoType *type;
+               MonoClassField *field;
+
+               if (is_sre_field_builder (mono_object_class (f->fb)))
+                       field = ((MonoReflectionFieldBuilder*)f->fb)->handle;
+               else if (is_sr_mono_field (mono_object_class (f->fb)))
+                       field = ((MonoReflectionField*)f->fb)->field;
+               else
+                       g_error ("resolve_object:: can't handle a FTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (f->fb)));
+
+               MonoType *finst = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst, error);
+               return_val_if_nok (error, NULL);
+               type = mono_class_inflate_generic_type_checked (finst, context, error);
+               return_val_if_nok (error, NULL);
+
+               inflated = mono_class_from_mono_type (type);
+
+               result = field = mono_class_get_field_from_name (inflated, mono_field_get_name (field));
+               ensure_complete_type (field->parent, error);
+               if (!is_ok (error)) {
+                       mono_metadata_free_type (type);
+                       return NULL;
+               }
+
+               g_assert (result);
+               mono_metadata_free_type (type);
+               *handle_class = mono_defaults.fieldhandle_class;
+       } else if (strcmp (obj->vtable->klass->name, "ConstructorOnTypeBuilderInst") == 0) {
+               MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj;
+               MonoType *cinst = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst, error);
+               return_val_if_nok (error, NULL);
+               MonoType *type = mono_class_inflate_generic_type_checked (cinst, context, error);
+               return_val_if_nok (error, NULL);
+
+               MonoClass *inflated_klass = mono_class_from_mono_type (type);
+               MonoMethod *method;
+
+               if (mono_is_sre_ctor_builder (mono_object_class (c->cb)))
+                       method = ((MonoReflectionCtorBuilder *)c->cb)->mhandle;
+               else if (mono_is_sr_mono_cmethod (mono_object_class (c->cb)))
+                       method = ((MonoReflectionMethod *)c->cb)->method;
+               else
+                       g_error ("resolve_object:: can't handle a CTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (c->cb)));
+
+               result = inflate_mono_method (inflated_klass, method, (MonoObject*)c->cb);
+               *handle_class = mono_defaults.methodhandle_class;
+               mono_metadata_free_type (type);
+       } else if (strcmp (obj->vtable->klass->name, "MethodOnTypeBuilderInst") == 0) {
+               MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
+               if (m->method_args) {
+                       result = mono_reflection_method_on_tb_inst_get_handle (m, error);
+                       return_val_if_nok (error, NULL);
+                       if (context) {
+                               result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
+                               mono_error_assert_ok (error);
+                       }
+               } else {
+                       MonoType *minst = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
+                       return_val_if_nok (error, NULL);
+                       MonoType *type = mono_class_inflate_generic_type_checked (minst, context, error);
+                       return_val_if_nok (error, NULL);
+
+                       MonoClass *inflated_klass = mono_class_from_mono_type (type);
+                       MonoMethod *method;
+
+                       if (is_sre_method_builder (mono_object_class (m->mb)))
+                               method = ((MonoReflectionMethodBuilder *)m->mb)->mhandle;
+                       else if (is_sr_mono_method (mono_object_class (m->mb)))
+                               method = ((MonoReflectionMethod *)m->mb)->method;
+                       else
+                               g_error ("resolve_object:: can't handle a MTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (m->mb)));
+
+                       result = inflate_mono_method (inflated_klass, method, (MonoObject*)m->mb);
+                       mono_metadata_free_type (type);
+               }
+               *handle_class = mono_defaults.methodhandle_class;
+       } else if (strcmp (obj->vtable->klass->name, "MonoArrayMethod") == 0) {
+               MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod*)obj;
+               MonoType *mtype;
+               MonoClass *klass;
+               MonoMethod *method;
+               gpointer iter;
+               char *name;
+
+               mtype = mono_reflection_type_get_handle (m->parent, error);
+               return_val_if_nok (error, NULL);
+               klass = mono_class_from_mono_type (mtype);
+
+               /* Find the method */
+
+               name = mono_string_to_utf8_checked (m->name, error);
+               return_val_if_nok (error, NULL);
+               iter = NULL;
+               while ((method = mono_class_get_methods (klass, &iter))) {
+                       if (!strcmp (method->name, name))
+                               break;
+               }
+               g_free (name);
+
+               // FIXME:
+               g_assert (method);
+               // FIXME: Check parameters/return value etc. match
+
+               result = method;
+               *handle_class = mono_defaults.methodhandle_class;
+       } else if (is_sre_array (mono_object_get_class(obj)) ||
+                               is_sre_byref (mono_object_get_class(obj)) ||
+                               is_sre_pointer (mono_object_get_class(obj))) {
+               MonoReflectionType *ref_type = (MonoReflectionType *)obj;
+               MonoType *type = mono_reflection_type_get_handle (ref_type, error);
+               return_val_if_nok (error, NULL);
+
+               if (context) {
+                       MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
+                       return_val_if_nok (error, NULL);
+
+                       result = mono_class_from_mono_type (inflated);
+                       mono_metadata_free_type (inflated);
+               } else {
+                       result = mono_class_from_mono_type (type);
+               }
+               *handle_class = mono_defaults.typehandle_class;
+       } else {
+               g_print ("%s\n", obj->vtable->klass->name);
+               g_assert_not_reached ();
+       }
+       return result;
+}
+
+#else /* DISABLE_REFLECTION_EMIT */
+
+MonoArray*
+mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) 
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+void
+ves_icall_TypeBuilder_setup_internal_class (MonoReflectionTypeBuilder *tb)
+{
+       g_assert_not_reached ();
+}
+
+gboolean
+mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error)
+{
+       g_assert_not_reached ();
+       return FALSE;
+}
+
+void
+mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
+{
+       g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported.");
+}
+
+static void
+mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
+{
+       g_assert_not_reached ();
+}
+
+guint32
+mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
+{
+       g_assert_not_reached ();
+       return 0;
+}
+
+guint32
+mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types, MonoError *error)
+{
+       g_assert_not_reached ();
+       return 0;
+}
+
+guint32
+mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, 
+                        gboolean create_open_instance, gboolean register_token, MonoError *error)
+{
+       g_assert_not_reached ();
+       return 0;
+}
+
+void
+mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields)
+{
+       g_assert_not_reached ();
+}
+
+void
+mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
+{
+       mono_error_init (error);
+       *overrides = NULL;
+       *num_overrides = 0;
+}
+
+MonoReflectionEvent *
+ves_icall_TypeBuilder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+MonoReflectionType*
+ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+void
+ves_icall_GenericTypeParameterBuilder_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
+{
+       g_assert_not_reached ();
+}
+
+void 
+ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
+{
+}
+
+MonoType*
+mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
+{
+       mono_error_init (error);
+       if (!ref)
+               return NULL;
+       return ref->type;
+}
+
+#endif /* DISABLE_REFLECTION_EMIT */
+
+#ifndef DISABLE_REFLECTION_EMIT
+MonoMethod*
+mono_reflection_method_builder_to_mono_method (MonoReflectionMethodBuilder *mb, MonoError *error)
+{
+       MonoType *tb;
+       MonoClass *klass;
+
+       tb = mono_reflection_type_get_handle ((MonoReflectionType*)mb->type, error);
+       return_val_if_nok (error, NULL);
+       klass = mono_class_from_mono_type (tb);
+
+       return methodbuilder_to_mono_method (klass, mb, error);
+}
+#else /* DISABLE_REFLECTION_EMIT */
+MonoMethod*
+mono_reflection_method_builder_to_mono_method (MonoReflectionMethodBuilder *mb, MonoError *error)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+#endif /* DISABLE_REFLECTION_EMIT */
+
+gint32
+ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, gboolean create_open_instance)
+{
+       MONO_CHECK_ARG_NULL (obj, 0);
+
+       MonoError error;
+       gint32 result = mono_image_create_token (mb->dynamic_image, obj, create_open_instance, TRUE, &error);
+       mono_error_set_pending_exception (&error);
+       return result;
+}
+
+gint32
+ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
+                                       MonoReflectionMethod *method,
+                                       MonoArray *opt_param_types)
+{
+       MONO_CHECK_ARG_NULL (method, 0);
+
+       MonoError error;
+       gint32 result = mono_image_create_method_token (
+               mb->dynamic_image, (MonoObject *) method, opt_param_types, &error);
+       mono_error_set_pending_exception (&error);
+       return result;
+}
+
+void
+ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
+{
+       MonoError error;
+       mono_image_create_pefile (mb, file, &error);
+       mono_error_set_pending_exception (&error);
+}
+
+void
+ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
+{
+       MonoError error;
+       mono_image_build_metadata (mb, &error);
+       mono_error_set_pending_exception (&error);
+}
+
+void
+ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, guint32 token)
+{
+       mono_image_register_token (mb->dynamic_image, token, obj);
+}
+
+MonoObject*
+ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilder *mb, guint32 token)
+{
+       MonoObject *obj;
+
+       mono_loader_lock ();
+       obj = (MonoObject *)mono_g_hash_table_lookup (mb->dynamic_image->tokens, GUINT_TO_POINTER (token));
+       mono_loader_unlock ();
+
+       return obj;
+}
+
+/**
+ * ves_icall_TypeBuilder_create_generic_class:
+ * @tb: a TypeBuilder object
+ *
+ * (icall)
+ * Creates the generic class after all generic parameters have been added.
+ */
+void
+ves_icall_TypeBuilder_create_generic_class (MonoReflectionTypeBuilder *tb)
+{
+       MonoError error;
+       (void) mono_reflection_create_generic_class (tb, &error);
+       mono_error_set_pending_exception (&error);
+}
+
+#ifndef DISABLE_REFLECTION_EMIT
+MonoArray*
+ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
+{
+       MonoError error;
+       MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
+       mono_error_set_pending_exception (&error);
+       return result;
+}
+#endif
+
+void
+ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
+{
+       mono_reflection_dynimage_basic_init (assemblyb);
+}
+
+MonoBoolean
+ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
+{
+       return mono_type_is_generic_parameter (tb->type.type);
+}
+
+void
+ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
+                                                                          MonoReflectionType *t)
+{
+       enumtype->type = t->type;
+}
+
+MonoReflectionType*
+ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
+{
+       MonoError error;
+       MonoReflectionType *ret;
+       MonoClass *klass;
+       int isbyref = 0, rank;
+       char *p;
+       char *str = mono_string_to_utf8_checked (smodifiers, &error);
+       if (mono_error_set_pending_exception (&error))
+               return NULL;
+
+       klass = mono_class_from_mono_type (tb->type.type);
+       p = str;
+       /* logic taken from mono_reflection_parse_type(): keep in sync */
+       while (*p) {
+               switch (*p) {
+               case '&':
+                       if (isbyref) { /* only one level allowed by the spec */
+                               g_free (str);
+                               return NULL;
+                       }
+                       isbyref = 1;
+                       p++;
+
+                       g_free (str);
+
+                       ret = mono_type_get_object_checked (mono_object_domain (tb), &klass->this_arg, &error);
+                       mono_error_set_pending_exception (&error);
+
+                       return ret;
+               case '*':
+                       klass = mono_ptr_class_get (&klass->byval_arg);
+                       mono_class_init (klass);
+                       p++;
+                       break;
+               case '[':
+                       rank = 1;
+                       p++;
+                       while (*p) {
+                               if (*p == ']')
+                                       break;
+                               if (*p == ',')
+                                       rank++;
+                               else if (*p != '*') { /* '*' means unknown lower bound */
+                                       g_free (str);
+                                       return NULL;
+                               }
+                               ++p;
+                       }
+                       if (*p != ']') {
+                               g_free (str);
+                               return NULL;
+                       }
+                       p++;
+                       klass = mono_array_class_get (klass, rank);
+                       mono_class_init (klass);
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       g_free (str);
+
+       ret = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
+       mono_error_set_pending_exception (&error);
+
+       return ret;
+}
+
+void
+ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilder *moduleb)
+{
+       mono_image_module_basic_init (moduleb);
+}
+
+guint32
+ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilder *module, MonoString *str)
+{
+       return mono_image_insert_string (module, str);
+}
+
+void
+ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilder *moduleb, MonoReflectionType *type)
+{
+       MonoDynamicImage *image = moduleb->dynamic_image;
+
+       g_assert (type->type);
+       image->wrappers_type = mono_class_from_mono_type (type->type);
+}
index c15d5be8ad134fdac250e1280362368eb263f58e..0821d28ae320db0a1803d763c32e629414118aba 100644 (file)
@@ -430,6 +430,9 @@ domain_get (MonoDomain *domain, gboolean create)
        }
 
        if (create) {
+               g_assert(!domain->cleanup_semaphore);
+               domain->cleanup_semaphore = CreateSemaphore(NULL, 0, 1, NULL);
+
                tpdomain = g_new0 (ThreadPoolDomain, 1);
                tpdomain->domain = domain;
                domain_add (tpdomain);
@@ -681,10 +684,13 @@ worker_thread (gpointer data)
                g_assert (tpdomain->domain->threadpool_jobs >= 0);
 
                if (tpdomain->domain->threadpool_jobs == 0 && mono_domain_is_unloading (tpdomain->domain)) {
-                       gboolean removed = domain_remove (tpdomain);
+                       gboolean removed;
+
+                       removed = domain_remove(tpdomain);
                        g_assert (removed);
-                       if (tpdomain->domain->cleanup_semaphore)
-                               ReleaseSemaphore (tpdomain->domain->cleanup_semaphore, 1, NULL);
+
+                       g_assert(tpdomain->domain->cleanup_semaphore);
+                       ReleaseSemaphore (tpdomain->domain->cleanup_semaphore, 1, NULL);
                        domain_free (tpdomain);
                        tpdomain = NULL;
                }
@@ -1427,9 +1433,9 @@ mono_threadpool_ms_end_invoke (MonoAsyncResult *ares, MonoArray **out_args, Mono
 gboolean
 mono_threadpool_ms_remove_domain_jobs (MonoDomain *domain, int timeout)
 {
-       gboolean res = TRUE;
-       gint64 end;
-       gpointer sem;
+       guint32 res;
+       gint64 now, end;
+       ThreadPoolDomain *tpdomain;
 
        g_assert (domain);
        g_assert (timeout >= -1);
@@ -1448,38 +1454,43 @@ mono_threadpool_ms_remove_domain_jobs (MonoDomain *domain, int timeout)
 #endif
 
        /*
-        * There might be some threads out that could be about to execute stuff from the given domain.
-        * We avoid that by setting up a semaphore to be pulsed by the thread that reaches zero.
-        */
-       sem = domain->cleanup_semaphore = CreateSemaphore (NULL, 0, 1, NULL);
+       * There might be some threads out that could be about to execute stuff from the given domain.
+       * We avoid that by waiting on a semaphore to be pulsed by the thread that reaches zero.
+       * The semaphore is only created for domains which queued threadpool jobs.
+       * We always wait on the semaphore rather than ensuring domain->threadpool_jobs is 0.
+       * There may be pending outstanding requests which will create new jobs.
+       * The semaphore is signaled the threadpool domain has been removed from list
+       * and we know no more jobs for the domain will be processed.
+       */
+
+       mono_lazy_initialize(&status, initialize);
+       mono_coop_mutex_lock(&threadpool->domains_lock);
+
+       tpdomain = domain_get(domain, FALSE);
+       if (!tpdomain || tpdomain->outstanding_request == 0) {
+               mono_coop_mutex_unlock(&threadpool->domains_lock);
+               return TRUE;
+       }
+       g_assert(domain->cleanup_semaphore);
 
-       /*
-        * The memory barrier here is required to have global ordering between assigning to cleanup_semaphone
-        * and reading threadpool_jobs. Otherwise this thread could read a stale version of threadpool_jobs
-        * and wait forever.
-        */
-       mono_memory_write_barrier ();
-
-       while (domain->threadpool_jobs) {
-               gint64 now;
-
-               if (timeout != -1) {
-                       now = mono_msec_ticks ();
-                       if (now > end) {
-                               res = FALSE;
-                               break;
-                       }
+       if (timeout != -1) {
+               now = mono_msec_ticks();
+               if (now > end) {
+                       mono_coop_mutex_unlock(&threadpool->domains_lock);
+                       return FALSE;
                }
-
-               MONO_ENTER_GC_SAFE;
-               WaitForSingleObject (sem, timeout != -1 ? end - now : timeout);
-               MONO_EXIT_GC_SAFE;
        }
 
+       MONO_ENTER_GC_SAFE;
+       res = WaitForSingleObjectEx(domain->cleanup_semaphore, timeout != -1 ? end - now : timeout, FALSE);
+       MONO_EXIT_GC_SAFE;
+
+       CloseHandle(domain->cleanup_semaphore);
        domain->cleanup_semaphore = NULL;
-       CloseHandle (sem);
 
-       return res;
+       mono_coop_mutex_unlock(&threadpool->domains_lock);
+
+       return res == WAIT_OBJECT_0;
 }
 
 void
index 5b910191f6c4ff0adba5cc680d20d653d034cfb4..e27e89bb6f088f3df2316861be72abb028de114e 100644 (file)
@@ -81,7 +81,7 @@ HANDLE ves_icall_System_Threading_Mutex_OpenMutex_internal (MonoString *name, gi
 HANDLE ves_icall_System_Threading_Semaphore_CreateSemaphore_internal (gint32 initialCount, gint32 maximumCount, MonoString *name, gint32 *error);
 MonoBoolean ves_icall_System_Threading_Semaphore_ReleaseSemaphore_internal (HANDLE handle, gint32 releaseCount, gint32 *prevcount);
 HANDLE ves_icall_System_Threading_Semaphore_OpenSemaphore_internal (MonoString *name, gint32 rights, gint32 *error);
-HANDLE ves_icall_System_Threading_Events_CreateEvent_internal (MonoBoolean manual, MonoBoolean initial, MonoString *name, MonoBoolean *created);
+HANDLE ves_icall_System_Threading_Events_CreateEvent_internal (MonoBoolean manual, MonoBoolean initial, MonoString *name, gint32 *error);
 gboolean ves_icall_System_Threading_Events_SetEvent_internal (HANDLE handle);
 gboolean ves_icall_System_Threading_Events_ResetEvent_internal (HANDLE handle);
 void ves_icall_System_Threading_Events_CloseEvent_internal (HANDLE handle);
@@ -258,4 +258,8 @@ mono_threads_attach_coop (MonoDomain *domain, gpointer *dummy);
 MONO_API void
 mono_threads_detach_coop (gpointer cookie, gpointer *dummy);
 
+void mono_threads_begin_abort_protected_block (void);
+void mono_threads_end_abort_protected_block (void);
+MonoException* mono_thread_try_resume_interruption (void);
+
 #endif /* _MONO_METADATA_THREADS_TYPES_H_ */
index 8ae79d05d99dfdc68bbe473398d18d8c9e377775..4c3ca385941daa308a8c4c1a04d5b34284ac81af 100644 (file)
@@ -44,6 +44,7 @@
 #include <mono/utils/mono-memory-model.h>
 #include <mono/utils/mono-threads-coop.h>
 #include <mono/utils/mono-error-internals.h>
+#include <mono/utils/w32handle.h>
 
 #include <mono/metadata/gc-internals.h>
 #include <mono/metadata/reflection-internals.h>
@@ -82,14 +83,6 @@ extern int tkill (pid_t tid, int signal);
 #define LOCK_THREAD(thread) lock_thread((thread))
 #define UNLOCK_THREAD(thread) unlock_thread((thread))
 
-typedef struct
-{
-       guint32 (*func)(void *);
-       MonoThread *obj;
-       MonoObject *delegate;
-       void *start_arg;
-} StartInfo;
-
 typedef union {
        gint32 ival;
        gfloat fval;
@@ -150,7 +143,7 @@ static MonoReferenceQueue *context_queue;
 
 /*
  * Threads which are starting up and they are not in the 'threads' hash yet.
- * When handle_store is called for a thread, it will be removed from this hash table.
+ * When mono_thread_attach_internal is called for a thread, it will be removed from this hash table.
  * Protected by mono_threads_lock ().
  */
 static MonoGHashTable *threads_starting_up = NULL;
@@ -191,7 +184,6 @@ static MonoThreadCleanupFunc mono_thread_cleanup_fn = NULL;
 static guint32 default_stacksize = 0;
 #define default_stacksize_for_thread(thread) ((thread)->stack_size? (thread)->stack_size: default_stacksize)
 
-static void thread_adjust_static_data (MonoInternalThread *thread);
 static void context_adjust_static_data (MonoAppContext *ctx);
 static void mono_free_static_data (gpointer* static_data);
 static void mono_init_static_data_info (StaticDataInfo *static_data);
@@ -269,87 +261,6 @@ thread_get_tid (MonoInternalThread *thread)
        return MONO_UINT_TO_NATIVE_THREAD_ID (thread->tid);
 }
 
-/* handle_store() and handle_remove() manage the array of threads that
- * still need to be waited for when the main thread exits.
- *
- * If handle_store() returns FALSE the thread must not be started
- * because Mono is shutting down.
- */
-static gboolean handle_store(MonoThread *thread, gboolean force_attach)
-{
-       mono_threads_lock ();
-
-       THREAD_DEBUG (g_message ("%s: thread %p ID %"G_GSIZE_FORMAT, __func__, thread, (gsize)thread->internal_thread->tid));
-
-       if (threads_starting_up)
-               mono_g_hash_table_remove (threads_starting_up, thread);
-
-       if (shutting_down && !force_attach) {
-               mono_threads_unlock ();
-               return FALSE;
-       }
-
-       if(threads==NULL) {
-               MONO_GC_REGISTER_ROOT_FIXED (threads, MONO_ROOT_SOURCE_THREADING, "threads table");
-               threads=mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_THREADING, "threads table");
-       }
-
-       /* We don't need to duplicate thread->handle, because it is
-        * only closed when the thread object is finalized by the GC.
-        */
-       g_assert (thread->internal_thread);
-       mono_g_hash_table_insert(threads, (gpointer)(gsize)(thread->internal_thread->tid),
-                                thread->internal_thread);
-
-       mono_threads_unlock ();
-
-       return TRUE;
-}
-
-static gboolean handle_remove(MonoInternalThread *thread)
-{
-       gboolean ret;
-       gsize tid = thread->tid;
-
-       THREAD_DEBUG (g_message ("%s: thread ID %"G_GSIZE_FORMAT, __func__, tid));
-
-       mono_threads_lock ();
-
-       if (threads) {
-               /* We have to check whether the thread object for the
-                * tid is still the same in the table because the
-                * thread might have been destroyed and the tid reused
-                * in the meantime, in which case the tid would be in
-                * the table, but with another thread object.
-                */
-               if (mono_g_hash_table_lookup (threads, (gpointer)tid) == thread) {
-                       mono_g_hash_table_remove (threads, (gpointer)tid);
-                       ret = TRUE;
-               } else {
-                       ret = FALSE;
-               }
-       }
-       else
-               ret = FALSE;
-       
-       mono_threads_unlock ();
-
-       /* Don't close the handle here, wait for the object finalizer
-        * to do it. Otherwise, the following race condition applies:
-        *
-        * 1) Thread exits (and handle_remove() closes the handle)
-        *
-        * 2) Some other handle is reassigned the same slot
-        *
-        * 3) Another thread tries to join the first thread, and
-        * blocks waiting for the reassigned handle to be signalled
-        * (which might never happen).  This is possible, because the
-        * thread calling Join() still has a reference to the first
-        * thread's object.
-        */
-       return ret;
-}
-
 static void ensure_synch_cs_set (MonoInternalThread *thread)
 {
        MonoCoopMutex *synch_cs;
@@ -405,6 +316,8 @@ is_threadabort_exception (MonoClass *klass)
  */
 static void thread_cleanup (MonoInternalThread *thread)
 {
+       gboolean ret;
+
        g_assert (thread != NULL);
 
        if (thread->abort_state_handle) {
@@ -453,13 +366,45 @@ static void thread_cleanup (MonoInternalThread *thread)
        if (InterlockedExchange (&thread->interruption_requested, 0))
                InterlockedDecrement (&thread_interruption_requested);
 
+       mono_threads_lock ();
+
+       if (!threads) {
+               ret = FALSE;
+       } else if (mono_g_hash_table_lookup (threads, (gpointer)thread->tid) != thread) {
+               /* We have to check whether the thread object for the
+                * tid is still the same in the table because the
+                * thread might have been destroyed and the tid reused
+                * in the meantime, in which case the tid would be in
+                * the table, but with another thread object.
+                */
+               ret = FALSE;
+       } else {
+               mono_g_hash_table_remove (threads, (gpointer)thread->tid);
+               ret = TRUE;
+       }
+
+       mono_threads_unlock ();
+
+       /* Don't close the handle here, wait for the object finalizer
+        * to do it. Otherwise, the following race condition applies:
+        *
+        * 1) Thread exits (and thread_cleanup() closes the handle)
+        *
+        * 2) Some other handle is reassigned the same slot
+        *
+        * 3) Another thread tries to join the first thread, and
+        * blocks waiting for the reassigned handle to be signalled
+        * (which might never happen).  This is possible, because the
+        * thread calling Join() still has a reference to the first
+        * thread's object.
+        */
+
        /* if the thread is not in the hash it has been removed already */
-       if (!handle_remove (thread)) {
+       if (!ret) {
                if (thread == mono_thread_internal_current ()) {
                        mono_domain_unset ();
                        mono_memory_barrier ();
                }
-               /* This needs to be called even if handle_remove () fails */
                if (mono_thread_cleanup_fn)
                        mono_thread_cleanup_fn (thread_get_tid (thread));
                return;
@@ -635,85 +580,146 @@ create_internal_thread (void)
        return thread;
 }
 
+static void 
+mono_alloc_static_data (gpointer **static_data_ptr, guint32 offset, gboolean threadlocal);
+
 static gboolean
-init_root_domain_thread (MonoInternalThread *thread, MonoThread *candidate)
+mono_thread_attach_internal (MonoThread *thread, gboolean force_attach, gboolean force_domain, gsize *stack_ptr)
 {
-       MonoDomain *domain = mono_get_root_domain ();
+       MonoThreadInfo *info;
+       MonoInternalThread *internal;
+       MonoDomain *domain, *root_domain;
+
+       g_assert (thread);
+
+       info = mono_thread_info_current ();
+
+       internal = thread->internal_thread;
+       internal->handle = mono_thread_info_get_handle (info);
+       internal->tid = MONO_NATIVE_THREAD_ID_TO_UINT (mono_native_thread_id_get ());
+       internal->thread_info = info;
+       internal->small_id = info->small_id;
+       internal->stack_ptr = stack_ptr;
+
+       THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Setting current_object_key to %p", __func__, mono_native_thread_id_get (), internal));
+
+       SET_CURRENT_OBJECT (internal);
 
-       if (!candidate || candidate->obj.vtable->domain != domain) {
-               candidate = new_thread_with_internal (domain, thread);
+       domain = mono_object_domain (thread);
+
+       mono_thread_push_appdomain_ref (domain);
+       if (!mono_domain_set (domain, force_domain)) {
+               mono_thread_pop_appdomain_ref ();
+               return FALSE;
+       }
+
+       mono_threads_lock ();
+
+       if (threads_starting_up)
+               mono_g_hash_table_remove (threads_starting_up, thread);
+
+       if (shutting_down && !force_attach) {
+               mono_threads_unlock ();
+               return FALSE;
+       }
+
+       if (!threads) {
+               MONO_GC_REGISTER_ROOT_FIXED (threads, MONO_ROOT_SOURCE_THREADING, "threads table");
+               threads = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_THREADING, "threads table");
+       }
+
+       /* We don't need to duplicate thread->handle, because it is
+        * only closed when the thread object is finalized by the GC. */
+       mono_g_hash_table_insert (threads, (gpointer)(gsize)(internal->tid), internal);
+
+       /* We have to do this here because mono_thread_start_cb
+        * requires that root_domain_thread is set up. */
+       if (thread_static_info.offset || thread_static_info.idx > 0) {
+               /* get the current allocated size */
+               guint32 offset = MAKE_SPECIAL_STATIC_OFFSET (thread_static_info.idx, thread_static_info.offset, 0);
+               mono_alloc_static_data (&internal->static_data, offset, TRUE);
        }
-       set_current_thread_for_domain (domain, thread, candidate);
-       g_assert (!thread->root_domain_thread);
-       MONO_OBJECT_SETREF (thread, root_domain_thread, candidate);
+
+       mono_threads_unlock ();
+
+       root_domain = mono_get_root_domain ();
+
+       g_assert (!internal->root_domain_thread);
+       if (domain != root_domain)
+               MONO_OBJECT_SETREF (internal, root_domain_thread, new_thread_with_internal (root_domain, internal));
+       else
+               MONO_OBJECT_SETREF (internal, root_domain_thread, thread);
+
+       if (domain != root_domain)
+               set_current_thread_for_domain (root_domain, internal, internal->root_domain_thread);
+
+       set_current_thread_for_domain (domain, internal, thread);
+
+       THREAD_DEBUG (g_message ("%s: Attached thread ID %"G_GSIZE_FORMAT" (handle %p)", __func__, internal->tid, internal->handle));
+
        return TRUE;
 }
 
-static guint32 WINAPI start_wrapper_internal(void *data)
+typedef struct {
+       gint32 ref;
+       MonoThread *thread;
+       MonoObject *start_delegate;
+       MonoObject *start_delegate_arg;
+       MonoThreadStart start_func;
+       gpointer start_func_arg;
+       gboolean failed;
+       MonoCoopSem registered;
+} StartInfo;
+
+static guint32 WINAPI start_wrapper_internal(StartInfo *start_info, gsize *stack_ptr)
 {
        MonoError error;
-       MonoThreadInfo *info;
-       StartInfo *start_info = (StartInfo *)data;
-       guint32 (*start_func)(void *);
-       void *start_arg;
+       MonoThreadStart start_func;
+       void *start_func_arg;
        gsize tid;
        /* 
-        * We don't create a local to hold start_info->obj, so hopefully it won't get pinned during a
+        * We don't create a local to hold start_info->thread, so hopefully it won't get pinned during a
         * GC stack walk.
         */
-       MonoInternalThread *internal = start_info->obj->internal_thread;
-       MonoObject *start_delegate = start_info->delegate;
-       MonoDomain *domain = start_info->obj->obj.vtable->domain;
+       MonoThread *thread;
+       MonoInternalThread *internal;
+       MonoObject *start_delegate;
+       MonoObject *start_delegate_arg;
+       MonoDomain *domain;
 
-       THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Start wrapper", __func__, mono_native_thread_id_get ()));
+       thread = start_info->thread;
+       internal = thread->internal_thread;
+       domain = mono_object_domain (start_info->thread);
 
-       /* We can be sure start_info->obj->tid and
-        * start_info->obj->handle have been set, because the thread
-        * was created suspended, and these values were set before the
-        * thread resumed
-        */
+       THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Start wrapper", __func__, mono_native_thread_id_get ()));
 
-       info = mono_thread_info_current ();
-       g_assert (info);
-       internal->thread_info = info;
-       internal->small_id = info->small_id;
+       if (!mono_thread_attach_internal (thread, FALSE, FALSE, stack_ptr)) {
+               start_info->failed = TRUE;
 
-       tid = internal->tid;
+               mono_coop_sem_post (&start_info->registered);
 
-       SET_CURRENT_OBJECT (internal);
+               if (InterlockedDecrement (&start_info->ref) == 0) {
+                       mono_coop_sem_destroy (&start_info->registered);
+                       g_free (start_info);
+               }
 
-       /* Every thread references the appdomain which created it */
-       mono_thread_push_appdomain_ref (domain);
-       
-       if (!mono_domain_set (domain, FALSE)) {
-               /* No point in raising an appdomain_unloaded exception here */
-               /* FIXME: Cleanup here */
-               mono_thread_pop_appdomain_ref ();
                return 0;
        }
 
-       start_func = start_info->func;
-       start_arg = start_info->obj->start_obj;
-       if (!start_arg)
-               start_arg = start_info->start_arg;
+       tid = internal->tid;
 
-       /* We have to do this here because mono_thread_new_init()
-          requires that root_domain_thread is set up. */
-       thread_adjust_static_data (internal);
-       init_root_domain_thread (internal, start_info->obj);
+       start_delegate = start_info->start_delegate;
+       start_delegate_arg = start_info->start_delegate_arg;
+       start_func = start_info->start_func;
+       start_func_arg = start_info->start_func_arg;
 
        /* This MUST be called before any managed code can be
         * executed, as it calls the callback function that (for the
         * jit) sets the lmf marker.
         */
-       mono_thread_new_init (tid, &tid, start_func);
-       internal->stack_ptr = &tid;
-       if (domain != mono_get_root_domain ())
-               set_current_thread_for_domain (domain, internal, start_info->obj);
 
-       LIBGC_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT",%d) Setting thread stack to %p", __func__, mono_native_thread_id_get (), getpid (), thread->stack_ptr));
-
-       THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Setting current_object_key to %p", __func__, mono_native_thread_id_get (), internal));
+       if (mono_thread_start_cb)
+               mono_thread_start_cb (tid, stack_ptr, start_func);
 
        /* On 2.0 profile (and higher), set explicitly since state might have been
           Unknown */
@@ -722,16 +728,16 @@ static guint32 WINAPI start_wrapper_internal(void *data)
 
        mono_thread_init_apartment_state ();
 
-       if(internal->start_notify!=NULL) {
-               /* Let the thread that called Start() know we're
-                * ready
-                */
-               ReleaseSemaphore (internal->start_notify, 1, NULL);
+       /* Let the thread that called Start() know we're ready */
+       mono_coop_sem_post (&start_info->registered);
+
+       if (InterlockedDecrement (&start_info->ref) == 0) {
+               mono_coop_sem_destroy (&start_info->registered);
+               g_free (start_info);
        }
 
-       g_free (start_info);
-       THREAD_DEBUG (g_message ("%s: start_wrapper for %"G_GSIZE_FORMAT, __func__,
-                                                        internal->tid));
+       /* start_info is not valid anymore */
+       start_info = NULL;
 
        /* 
         * Call this after calling start_notify, since the profiler callback might want
@@ -750,12 +756,14 @@ static guint32 WINAPI start_wrapper_internal(void *data)
 
        /* start_func is set only for unmanaged start functions */
        if (start_func) {
-               start_func (start_arg);
+               start_func (start_func_arg);
        } else {
                void *args [1];
+
                g_assert (start_delegate != NULL);
-               args [0] = start_arg;
+
                /* we may want to handle the exception here. See comment below on unhandled exceptions */
+               args [0] = (gpointer) start_delegate_arg;
                mono_runtime_delegate_invoke_checked (start_delegate, args, &error);
 
                if (!mono_error_ok (&error)) {
@@ -807,12 +815,12 @@ static guint32 WINAPI start_wrapper_internal(void *data)
 
 static gsize WINAPI start_wrapper(void *data)
 {
-       volatile int dummy;
+       volatile gsize dummy;
 
        /* Avoid scanning the frames above this frame during a GC */
        mono_gc_set_stack_end ((void*)&dummy);
 
-       return start_wrapper_internal (data);
+       return start_wrapper_internal ((StartInfo*) data, (gsize*) &dummy);
 }
 
 /*
@@ -822,12 +830,19 @@ static gsize WINAPI start_wrapper(void *data)
  * LOCKING: Acquires the threads lock.
  */
 static gboolean
-create_thread (MonoThread *thread, MonoInternalThread *internal, StartInfo *start_info, gboolean threadpool_thread, guint32 stack_size,
-                          MonoError *error)
+create_thread (MonoThread *thread, MonoInternalThread *internal, MonoObject *start_delegate, MonoThreadStart start_func, gpointer start_func_arg,
+       gboolean threadpool_thread, guint32 stack_size, MonoError *error)
 {
+       StartInfo *start_info = NULL;
        HANDLE thread_handle;
        MonoNativeThreadId tid;
        MonoThreadParm tp;
+       gboolean ret;
+
+       if (start_delegate)
+               g_assert (!start_func && !start_func_arg);
+       if (start_func)
+               g_assert (!start_delegate);
 
        /*
         * Join joinable threads to prevent running out of threads since the finalizer
@@ -839,7 +854,6 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, StartInfo *star
 
        mono_threads_lock ();
        if (shutting_down) {
-               g_free (start_info);
                mono_threads_unlock ();
                return FALSE;
        }
@@ -850,25 +864,26 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, StartInfo *star
        mono_g_hash_table_insert (threads_starting_up, thread, thread);
        mono_threads_unlock ();
 
-       internal->start_notify = CreateSemaphore (NULL, 0, 0x7fffffff, NULL);
-       if (!internal->start_notify) {
-               mono_threads_lock ();
-               mono_g_hash_table_remove (threads_starting_up, thread);
-               mono_threads_unlock ();
-               g_warning ("%s: CreateSemaphore error 0x%x", __func__, GetLastError ());
-               g_free (start_info);
-               return FALSE;
-       }
+       internal->threadpool_thread = threadpool_thread;
+       if (threadpool_thread)
+               mono_thread_set_state (internal, ThreadState_Background);
+
+       start_info = g_new0 (StartInfo, 1);
+       start_info->ref = 2;
+       start_info->thread = thread;
+       start_info->start_delegate = start_delegate;
+       start_info->start_delegate_arg = thread->start_obj;
+       start_info->start_func = start_func;
+       start_info->start_func_arg = start_func_arg;
+       start_info->failed = FALSE;
+       mono_coop_sem_init (&start_info->registered, 0);
 
        if (stack_size == 0)
                stack_size = default_stacksize_for_thread (internal);
 
-       /* Create suspended, so we can do some housekeeping before the thread
-        * starts
-        */
        tp.priority = thread->priority;
        tp.stack_size = stack_size;
-       tp.creation_flags = CREATE_SUSPENDED;
+       tp.creation_flags = 0;
 
        thread_handle = mono_threads_create_thread (start_wrapper, start_info, &tp, &tid);
 
@@ -877,50 +892,35 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, StartInfo *star
                mono_threads_lock ();
                mono_g_hash_table_remove (threads_starting_up, thread);
                mono_threads_unlock ();
-               g_free (start_info);
                mono_error_set_execution_engine (error, "Couldn't create thread. Error 0x%x", GetLastError());
-               return FALSE;
+               /* ref is not going to be decremented in start_wrapper_internal */
+               InterlockedDecrement (&start_info->ref);
+               ret = FALSE;
+               goto done;
        }
-       THREAD_DEBUG (g_message ("%s: Started thread ID %"G_GSIZE_FORMAT" (handle %p)", __func__, tid, thread_handle));
-
-       internal->handle = thread_handle;
-       internal->tid = MONO_NATIVE_THREAD_ID_TO_UINT (tid);
-
-       internal->threadpool_thread = threadpool_thread;
-       if (threadpool_thread)
-               mono_thread_set_state (internal, ThreadState_Background);
 
        THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Launching thread %p (%"G_GSIZE_FORMAT")", __func__, mono_native_thread_id_get (), internal, (gsize)internal->tid));
 
-       /* Only store the handle when the thread is about to be
-        * launched, to avoid the main thread deadlocking while trying
-        * to clean up a thread that will never be signalled.
+       /*
+        * Wait for the thread to set up its TLS data etc, so
+        * theres no potential race condition if someone tries
+        * to look up the data believing the thread has
+        * started
         */
-       if (!handle_store (thread, FALSE))
-               return FALSE;
 
-       mono_thread_info_resume (tid);
+       mono_coop_sem_wait (&start_info->registered, MONO_SEM_FLAGS_NONE);
 
-       if (internal->start_notify) {
-               /*
-                * Wait for the thread to set up its TLS data etc, so
-                * theres no potential race condition if someone tries
-                * to look up the data believing the thread has
-                * started
-                */
-               THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") waiting for thread %p (%"G_GSIZE_FORMAT") to start", __func__, mono_native_thread_id_get (), internal, (gsize)internal->tid));
+       THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Done launching thread %p (%"G_GSIZE_FORMAT")", __func__, mono_native_thread_id_get (), internal, (gsize)internal->tid));
 
-               MONO_ENTER_GC_SAFE;
-               WaitForSingleObjectEx (internal->start_notify, INFINITE, FALSE);
-               MONO_EXIT_GC_SAFE;
+       ret = !start_info->failed;
 
-               CloseHandle (internal->start_notify);
-               internal->start_notify = NULL;
+done:
+       if (InterlockedDecrement (&start_info->ref) == 0) {
+               mono_coop_sem_destroy (&start_info->registered);
+               g_free (start_info);
        }
 
-       THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Done launching thread %p (%"G_GSIZE_FORMAT")", __func__, mono_native_thread_id_get (), internal, (gsize)internal->tid));
-
-       return TRUE;
+       return ret;
 }
 
 void mono_thread_new_init (intptr_t tid, gpointer stack_start, gpointer func)
@@ -950,7 +950,6 @@ mono_thread_create_internal (MonoDomain *domain, gpointer func, gpointer arg, gb
 {
        MonoThread *thread;
        MonoInternalThread *internal;
-       StartInfo *start_info;
        gboolean res;
 
        mono_error_init (error);
@@ -962,12 +961,7 @@ mono_thread_create_internal (MonoDomain *domain, gpointer func, gpointer arg, gb
 
        MONO_OBJECT_SETREF (thread, internal_thread, internal);
 
-       start_info = g_new0 (StartInfo, 1);
-       start_info->func = (guint32 (*)(void *))func;
-       start_info->obj = thread;
-       start_info->start_arg = arg;
-
-       res = create_thread (thread, internal, start_info, threadpool_thread, stack_size, error);
+       res = create_thread (thread, internal, NULL, (MonoThreadStart) func, arg, threadpool_thread, stack_size, error);
        return_val_if_nok (error, NULL);
 
        /* Check that the managed and unmanaged layout of MonoInternalThread matches */
@@ -1004,13 +998,12 @@ mono_thread_attach (MonoDomain *domain)
 MonoThread *
 mono_thread_attach_full (MonoDomain *domain, gboolean force_attach)
 {
-       MonoThreadInfo *info;
-       MonoInternalThread *thread;
-       MonoThread *current_thread;
-       HANDLE thread_handle;
+       MonoInternalThread *internal;
+       MonoThread *thread;
        MonoNativeThreadId tid;
+       gsize stack_ptr;
 
-       if ((thread = mono_thread_internal_current ())) {
+       if ((internal = mono_thread_internal_current ())) {
                if (domain != mono_domain_get ())
                        mono_domain_set (domain, TRUE);
                /* Already attached */
@@ -1021,44 +1014,19 @@ mono_thread_attach_full (MonoDomain *domain, gboolean force_attach)
                g_error ("Thread %"G_GSIZE_FORMAT" calling into managed code is not registered with the GC. On UNIX, this can be fixed by #include-ing <gc.h> before <pthread.h> in the file containing the thread creation code.", mono_native_thread_id_get ());
        }
 
-       thread = create_internal_thread ();
-
-       thread_handle = mono_thread_info_open_handle ();
-       g_assert (thread_handle);
-
        tid=mono_native_thread_id_get ();
 
-       thread->handle = thread_handle;
-       thread->tid = MONO_NATIVE_THREAD_ID_TO_UINT (tid);
-       thread->stack_ptr = &tid;
-
-       THREAD_DEBUG (g_message ("%s: Attached thread ID %"G_GSIZE_FORMAT" (handle %p)", __func__, tid, thread_handle));
-
-       info = mono_thread_info_current ();
-       g_assert (info);
-       thread->thread_info = info;
-       thread->small_id = info->small_id;
+       internal = create_internal_thread ();
 
-       current_thread = new_thread_with_internal (domain, thread);
+       thread = new_thread_with_internal (domain, internal);
 
-       if (!handle_store (current_thread, force_attach)) {
+       if (!mono_thread_attach_internal (thread, force_attach, TRUE, &stack_ptr)) {
                /* Mono is shutting down, so just wait for the end */
                for (;;)
                        mono_thread_info_sleep (10000, NULL);
        }
 
-       THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Setting current_object_key to %p", __func__, mono_native_thread_id_get (), thread));
-
-       SET_CURRENT_OBJECT (thread);
-       mono_domain_set (domain, TRUE);
-
-       thread_adjust_static_data (thread);
-
-       init_root_domain_thread (thread, current_thread);
-
-       if (domain != mono_get_root_domain ())
-               set_current_thread_for_domain (domain, thread, current_thread);
-
+       THREAD_DEBUG (g_message ("%s: Attached thread ID %"G_GSIZE_FORMAT" (handle %p)", __func__, tid, internal->handle));
 
        if (mono_thread_attach_cb) {
                guint8 *staddr;
@@ -1067,17 +1035,17 @@ mono_thread_attach_full (MonoDomain *domain, gboolean force_attach)
                mono_thread_info_get_stack_bounds (&staddr, &stsize);
 
                if (staddr == NULL)
-                       mono_thread_attach_cb (MONO_NATIVE_THREAD_ID_TO_UINT (tid), &tid);
+                       mono_thread_attach_cb (MONO_NATIVE_THREAD_ID_TO_UINT (tid), &stack_ptr);
                else
                        mono_thread_attach_cb (MONO_NATIVE_THREAD_ID_TO_UINT (tid), staddr + stsize);
        }
 
        /* Can happen when we attach the profiler helper thread in order to heapshot. */
-       if (!info->tools_thread)
+       if (!mono_thread_info_current ()->tools_thread)
                // FIXME: Need a separate callback
                mono_profiler_thread_start (MONO_NATIVE_THREAD_ID_TO_UINT (tid));
 
-       return current_thread;
+       return thread;
 }
 
 void
@@ -1092,7 +1060,7 @@ mono_thread_detach_internal (MonoInternalThread *thread)
        SET_CURRENT_OBJECT (NULL);
        mono_domain_unset ();
 
-       /* Don't need to CloseHandle this thread, even though we took a
+       /* Don't need to close the handle to this thread, even though we took a
         * reference in mono_thread_attach (), because the GC will do it
         * when the Thread object is finalised.
         */
@@ -1162,7 +1130,6 @@ ves_icall_System_Threading_Thread_Thread_internal (MonoThread *this_obj,
                                                                                                   MonoObject *start)
 {
        MonoError error;
-       StartInfo *start_info;
        MonoInternalThread *internal;
        gboolean res;
 
@@ -1184,15 +1151,8 @@ ves_icall_System_Threading_Thread_Thread_internal (MonoThread *this_obj,
                UNLOCK_THREAD (internal);
                return this_obj;
        }
-       /* This is freed in start_wrapper */
-       start_info = g_new0 (StartInfo, 1);
-       start_info->func = NULL;
-       start_info->start_arg = NULL;
-       start_info->delegate = start;
-       start_info->obj = this_obj;
-       g_assert (this_obj->obj.vtable->domain == mono_domain_get ());
 
-       res = create_thread (this_obj, internal, start_info, FALSE, 0, &error);
+       res = create_thread (this_obj, internal, start, NULL, NULL, FALSE, 0, &error);
        if (!res) {
                mono_error_cleanup (&error);
                UNLOCK_THREAD (internal);
@@ -1221,7 +1181,7 @@ ves_icall_System_Threading_InternalThread_Thread_free_internal (MonoInternalThre
         * when thread_cleanup () can be called after this.
         */
        if (thread)
-               CloseHandle (thread);
+               mono_threads_close_thread_handle (thread);
 
        if (this_obj->synch_cs) {
                MonoCoopMutex *synch_cs = this_obj->synch_cs;
@@ -1697,7 +1657,7 @@ gint32 ves_icall_System_Threading_WaitHandle_WaitAll_internal(MonoArray *mono_ha
 gint32 ves_icall_System_Threading_WaitHandle_WaitAny_internal(MonoArray *mono_handles, gint32 ms)
 {
        MonoError error;
-       HANDLE handles [MAXIMUM_WAIT_OBJECTS];
+       HANDLE handles [MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS];
        uintptr_t numhandles;
        guint32 ret;
        guint32 i;
@@ -1709,7 +1669,7 @@ gint32 ves_icall_System_Threading_WaitHandle_WaitAny_internal(MonoArray *mono_ha
                return map_native_wait_result_to_managed (WAIT_FAILED);
 
        numhandles = mono_array_length(mono_handles);
-       if (numhandles > MAXIMUM_WAIT_OBJECTS)
+       if (numhandles > MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS)
                return map_native_wait_result_to_managed (WAIT_FAILED);
 
        for(i = 0; i < numhandles; i++) {       
@@ -1845,6 +1805,7 @@ HANDLE ves_icall_System_Threading_Semaphore_CreateSemaphore_internal (gint32 ini
        }
 
        *error = GetLastError ();
+
        return(sem);
 }                                                                   
 
@@ -1858,28 +1819,25 @@ HANDLE ves_icall_System_Threading_Semaphore_OpenSemaphore_internal (MonoString *
        HANDLE sem;
 
        sem = OpenSemaphore (rights, FALSE, mono_string_chars (name));
+
        *error = GetLastError ();
 
        return(sem);
 }
 
-HANDLE ves_icall_System_Threading_Events_CreateEvent_internal (MonoBoolean manual, MonoBoolean initial, MonoString *name, MonoBoolean *created)
+HANDLE ves_icall_System_Threading_Events_CreateEvent_internal (MonoBoolean manual, MonoBoolean initial, MonoString *name, gint32 *error)
 {
        HANDLE event;
-       
-       *created = TRUE;
 
        if (name == NULL) {
                event = CreateEvent (NULL, manual, initial, NULL);
        } else {
                event = CreateEvent (NULL, manual, initial,
                                     mono_string_chars (name));
-               
-               if (GetLastError () == ERROR_ALREADY_EXISTS) {
-                       *created = FALSE;
-               }
        }
-       
+
+       *error = GetLastError ();
+
        return(event);
 }
 
@@ -1902,13 +1860,13 @@ HANDLE ves_icall_System_Threading_Events_OpenEvent_internal (MonoString *name,
 {
        HANDLE ret;
        
-       *error = ERROR_SUCCESS;
-       
        ret = OpenEvent (rights, FALSE, mono_string_chars (name));
        if (ret == NULL) {
                *error = GetLastError ();
+       } else {
+               *error = ERROR_SUCCESS;
        }
-       
+
        return(ret);
 }
 
@@ -2993,12 +2951,13 @@ static void print_tids (gpointer key, gpointer value, gpointer user)
 
 struct wait_data 
 {
-       HANDLE handles[MAXIMUM_WAIT_OBJECTS];
-       MonoInternalThread *threads[MAXIMUM_WAIT_OBJECTS];
+       HANDLE handles[MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS];
+       MonoInternalThread *threads[MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS];
        guint32 num;
 };
 
-static void wait_for_tids (struct wait_data *wait, guint32 timeout)
+static void
+wait_for_tids (struct wait_data *wait, guint32 timeout)
 {
        guint32 i, ret;
        
@@ -3015,7 +2974,7 @@ static void wait_for_tids (struct wait_data *wait, guint32 timeout)
        }
        
        for(i=0; i<wait->num; i++)
-               CloseHandle (wait->handles[i]);
+               mono_threads_close_thread_handle (wait->handles [i]);
 
        if (ret == WAIT_TIMEOUT)
                return;
@@ -3062,7 +3021,7 @@ static void wait_for_tids_or_state_change (struct wait_data *wait, guint32 timeo
         * to background mode.
         */
        count = wait->num;
-       if (count < MAXIMUM_WAIT_OBJECTS) {
+       if (count < MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS) {
                wait->handles [count] = background_change_event;
                count++;
        }
@@ -3078,7 +3037,7 @@ static void wait_for_tids_or_state_change (struct wait_data *wait, guint32 timeo
        }
        
        for(i=0; i<wait->num; i++)
-               CloseHandle (wait->handles[i]);
+               mono_threads_close_thread_handle (wait->handles [i]);
 
        if (ret == WAIT_TIMEOUT)
                return;
@@ -3100,7 +3059,7 @@ static void build_wait_tids (gpointer key, gpointer value, gpointer user)
 {
        struct wait_data *wait=(struct wait_data *)user;
 
-       if(wait->num<MAXIMUM_WAIT_OBJECTS) {
+       if(wait->num<MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS) {
                HANDLE handle;
                MonoInternalThread *thread=(MonoInternalThread *)value;
 
@@ -3164,7 +3123,7 @@ remove_and_abort_threads (gpointer key, gpointer value, gpointer user)
        MonoInternalThread *thread = (MonoInternalThread *)value;
        HANDLE handle;
 
-       if (wait->num >= MAXIMUM_WAIT_OBJECTS)
+       if (wait->num >= MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS)
                return FALSE;
 
        /* The finalizer thread is not a background thread */
@@ -3268,7 +3227,7 @@ void mono_thread_manage (void)
                ResetEvent (background_change_event);
                wait->num=0;
                /*We must zero all InternalThread pointers to avoid making the GC unhappy.*/
-               memset (wait->threads, 0, MAXIMUM_WAIT_OBJECTS * SIZEOF_VOID_P);
+               memset (wait->threads, 0, MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS * SIZEOF_VOID_P);
                mono_g_hash_table_foreach (threads, build_wait_tids, wait);
                mono_threads_unlock ();
                if(wait->num>0) {
@@ -3294,7 +3253,7 @@ void mono_thread_manage (void)
 
                wait->num = 0;
                /*We must zero all InternalThread pointers to avoid making the GC unhappy.*/
-               memset (wait->threads, 0, MAXIMUM_WAIT_OBJECTS * SIZEOF_VOID_P);
+               memset (wait->threads, 0, MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS * SIZEOF_VOID_P);
                mono_g_hash_table_foreach_remove (threads, remove_and_abort_threads, wait);
 
                mono_threads_unlock ();
@@ -3322,7 +3281,7 @@ collect_threads_for_suspend (gpointer key, gpointer value, gpointer user_data)
        HANDLE handle;
 
        /* 
-        * We try to exclude threads early, to avoid running into the MAXIMUM_WAIT_OBJECTS
+        * We try to exclude threads early, to avoid running into the MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS
         * limitation.
         * This needs no locking.
         */
@@ -3330,7 +3289,7 @@ collect_threads_for_suspend (gpointer key, gpointer value, gpointer user_data)
                (thread->state & ThreadState_Stopped) != 0)
                return;
 
-       if (wait->num<MAXIMUM_WAIT_OBJECTS) {
+       if (wait->num<MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS) {
                handle = mono_threads_open_thread_handle (thread->handle, thread_get_tid (thread));
                if (handle == NULL)
                        return;
@@ -3373,7 +3332,7 @@ void mono_thread_suspend_all_other_threads (void)
 
        /*
         * We make multiple calls to WaitForMultipleObjects since:
-        * - we can only wait for MAXIMUM_WAIT_OBJECTS threads
+        * - we can only wait for MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS threads
         * - some threads could exit without becoming suspended
         */
        finished = FALSE;
@@ -3384,7 +3343,7 @@ void mono_thread_suspend_all_other_threads (void)
                 */
                wait->num = 0;
                /*We must zero all InternalThread pointers to avoid making the GC unhappy.*/
-               memset (wait->threads, 0, MAXIMUM_WAIT_OBJECTS * SIZEOF_VOID_P);
+               memset (wait->threads, 0, MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS * SIZEOF_VOID_P);
                mono_threads_lock ();
                mono_g_hash_table_foreach (threads, collect_threads_for_suspend, wait);
                mono_threads_unlock ();
@@ -3398,7 +3357,7 @@ void mono_thread_suspend_all_other_threads (void)
                             || mono_gc_is_finalizer_internal_thread (thread)
                             || (thread->flags & MONO_THREAD_FLAG_DONT_MANAGE)
                        ) {
-                               //CloseHandle (wait->handles [i]);
+                               //mono_threads_close_thread_handle (wait->handles [i]);
                                wait->threads [i] = NULL; /* ignore this thread in next loop */
                                continue;
                        }
@@ -3409,7 +3368,7 @@ void mono_thread_suspend_all_other_threads (void)
                                (thread->state & ThreadState_StopRequested) != 0 ||
                                (thread->state & ThreadState_Stopped) != 0) {
                                UNLOCK_THREAD (thread);
-                               CloseHandle (wait->handles [i]);
+                               mono_threads_close_thread_handle (wait->handles [i]);
                                wait->threads [i] = NULL; /* ignore this thread in next loop */
                                continue;
                        }
@@ -3858,7 +3817,7 @@ collect_appdomain_thread (gpointer key, gpointer value, gpointer user_data)
        if (mono_thread_internal_has_appdomain_ref (thread, domain)) {
                /* printf ("ABORTING THREAD %p BECAUSE IT REFERENCES DOMAIN %s.\n", thread->tid, domain->friendly_name); */
 
-               if(data->wait.num<MAXIMUM_WAIT_OBJECTS) {
+               if(data->wait.num<MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS) {
                        HANDLE handle = mono_threads_open_thread_handle (thread->handle, thread_get_tid (thread));
                        if (handle == NULL)
                                return;
@@ -4142,22 +4101,6 @@ mono_alloc_static_data_slot (StaticDataInfo *static_data, guint32 size, guint32
        return offset;
 }
 
-/* 
- * ensure thread static fields already allocated are valid for thread
- * This function is called when a thread is created or on thread attach.
- */
-static void
-thread_adjust_static_data (MonoInternalThread *thread)
-{
-       mono_threads_lock ();
-       if (thread_static_info.offset || thread_static_info.idx > 0) {
-               /* get the current allocated size */
-               guint32 offset = MAKE_SPECIAL_STATIC_OFFSET (thread_static_info.idx, thread_static_info.offset, 0);
-               mono_alloc_static_data (&thread->static_data, offset, TRUE);
-       }
-       mono_threads_unlock ();
-}
-
 /*
  * LOCKING: requires that threads_mutex is held
  */
@@ -4524,7 +4467,6 @@ mono_thread_request_interruption (gboolean running_managed)
                thread->state & ThreadState_Background)
                ExitThread (1);
 #endif
-       
        if (InterlockedCompareExchange (&thread->interruption_requested, 1, 0) == 1)
                return NULL;
        InterlockedIncrement (&thread_interruption_requested);
@@ -4803,6 +4745,13 @@ async_abort_critical (MonoThreadInfo *info, gpointer ud)
        if (mono_get_eh_callbacks ()->mono_install_handler_block_guard (mono_thread_info_get_suspend_state (info)))
                return MonoResumeThread;
 
+       /*
+       The target thread is running at least one protected block, which must not be interrupted, so we give up.
+       The protected block code will give them a chance when appropriate.
+       */
+       if (thread->abort_protected_block_count)
+               return MonoResumeThread;
+
        /*someone is already interrupting it*/
        if (InterlockedCompareExchange (&thread->interruption_requested, 1, 0) == 1)
                return MonoResumeThread;
@@ -4860,6 +4809,9 @@ self_abort_internal (MonoError *error)
        /* FIXME this is insanely broken, it doesn't cause interruption to happen synchronously
         * since passing FALSE to mono_thread_request_interruption makes sure it returns NULL */
 
+       /*
+       Self aborts ignore the protected block logic and raise the TAE regardless. This is verified by one of the tests in mono/tests/abort-cctor.cs.
+       */
        exc = mono_thread_request_interruption (TRUE);
        if (exc)
                mono_error_set_exception_instance (error, exc);
@@ -5065,17 +5017,16 @@ mono_thread_internal_check_for_interruption_critical (MonoInternalThread *thread
 void
 mono_thread_internal_unhandled_exception (MonoObject* exc)
 {
-       if (mono_runtime_unhandled_exception_policy_get () == MONO_UNHANDLED_POLICY_CURRENT) {
-               MonoClass *klass = exc->vtable->klass;
-               if (is_threadabort_exception (klass)) {
-                       mono_thread_internal_reset_abort (mono_thread_internal_current ());
-               } else if (!is_appdomainunloaded_exception (klass)) {
-                       mono_unhandled_exception (exc);
-                       if (mono_environment_exitcode_get () == 1) {
-                               mono_environment_exitcode_set (255);
-                               mono_invoke_unhandled_exception_hook (exc);
-                               g_assert_not_reached ();
-                       }
+       MonoClass *klass = exc->vtable->klass;
+       if (is_threadabort_exception (klass)) {
+               mono_thread_internal_reset_abort (mono_thread_internal_current ());
+       } else if (!is_appdomainunloaded_exception (klass)
+               && mono_runtime_unhandled_exception_policy_get () == MONO_UNHANDLED_POLICY_CURRENT) {
+               mono_unhandled_exception (exc);
+               if (mono_environment_exitcode_get () == 1) {
+                       mono_environment_exitcode_set (255);
+                       mono_invoke_unhandled_exception_hook (exc);
+                       g_assert_not_reached ();
                }
        }
 }
@@ -5185,3 +5136,36 @@ mono_threads_detach_coop (gpointer cookie, gpointer *dummy)
                }
        }
 }
+
+void
+mono_threads_begin_abort_protected_block (void)
+{
+       MonoInternalThread *thread;
+
+       thread = mono_thread_internal_current ();
+       ++thread->abort_protected_block_count;
+       mono_memory_barrier ();
+}
+
+void
+mono_threads_end_abort_protected_block (void)
+{
+       MonoInternalThread *thread;
+
+       thread = mono_thread_internal_current ();
+
+       mono_memory_barrier ();
+       --thread->abort_protected_block_count;
+}
+
+MonoException*
+mono_thread_try_resume_interruption (void)
+{
+       MonoInternalThread *thread;
+
+       thread = mono_thread_internal_current ();
+       if (thread->abort_protected_block_count || mono_get_eh_callbacks ()->mono_current_thread_has_handle_block_guard ())
+               return NULL;
+
+       return mono_thread_resume_interruption ();
+}
\ No newline at end of file
index 09b76d4a128204dd9f34f314c3d4514c5ded671b..7be7267baa5d7bdb303b6809640bb58b9f88c18b 100644 (file)
@@ -12,6 +12,7 @@
 #include <config.h>
 
 #include <mono/metadata/object-internals.h>
+#include <mono/metadata/dynamic-image-internals.h>
 #include <mono/metadata/verify.h>
 #include <mono/metadata/verify-internals.h>
 #include <mono/metadata/opcodes.h>
@@ -371,7 +372,7 @@ static gboolean
 token_bounds_check (MonoImage *image, guint32 token)
 {
        if (image_is_dynamic (image))
-               return mono_reflection_is_valid_dynamic_token ((MonoDynamicImage*)image, token);
+               return mono_dynamic_image_is_valid_token ((MonoDynamicImage*)image, token);
        return image->tables [mono_metadata_token_table (token)].rows >= mono_metadata_token_index (token) && mono_metadata_token_index (token) > 0;
 }
 
index 28f66c47f4be8d5fdd121046d8a700ebb4ce8ce5..8cc6e1d051e42ac9465eed8df37431de3dd22991 100644 (file)
@@ -32,4 +32,4 @@
 /mono-boehm
 /buildver-sgen.h
 /buildver-boehm.h
-/regressionexitcode.out
+/regressiontests.out
index e3983f69e2b4f769154a6b7cac805abfe91e71bb..62e771c78b912a21c14142bccfcf772d1b1fde9e 100755 (executable)
@@ -372,7 +372,8 @@ darwin_sources = \
        mini-darwin.c
 
 windows_sources = \
-       mini-windows.c
+       mini-windows.c \
+       mini-windows-dllmain.c
 
 posix_sources = \
        mini-posix.c
@@ -696,8 +697,16 @@ checktests: $(regtests)
        for i in $(regtests); do $(MINI_RUNTIME) $$i; done
 
 rcheck-nunit: mono $(regtests)
-       -($(MINI_RUNTIME) --regression $(regtests); echo $$? > regressionexitcode.out) | $(srcdir)/emitnunit.pl
-       exit $$(cat regressionexitcode.out)
+       $(MINI_RUNTIME) --regression $(regtests) > regressiontests.out 2>&1; cat regressiontests.out; \
+       if grep -q "100% pass" regressiontests.out; then successbool=True; failurescount=0; else successbool=False; failurescount=1; fi; \
+       echo "<?xml version='1.0' encoding='utf-8'?>\
+               <test-results failures='$$failurescount' total='1' not-run='0' name='regression-tests.dummy' date='$$(date +%F)' time='$$(date +%T)'>\
+                       <test-suite name='regression-tests.dummy' success='$$successbool' time='0'>\
+                               <results><test-case name='MonoTests.regressions.100percentsuccess' executed='True' success='$$successbool' time='0'>" > TestResult-regression.xml; \
+                                       if [ "$$successbool" = "False" ]; then echo "<failure><message><![CDATA[$$(cat regressiontests.out)]]></message><stack-trace></stack-trace></failure>" >> TestResult-regression.xml; fi; \
+                               echo "</test-case></results>\
+                       </test-suite>\
+               </test-results>" >> TestResult-regression.xml; exit $$failurescount
 
 rcheck: mono $(regtests)
        $(MINI_RUNTIME) --regression $(regtests)
@@ -833,7 +842,6 @@ CLEANFILES= $(BUILT_SOURCES) *.exe *.dll
 EXTRA_DIST = TestDriver.cs \
        TestHelpers.cs \
        genmdesc.pl                             \
-       emitnunit.pl                    \
        $(test_sources)                         \
        $(x86_sources) cpu-x86.md               \
        $(amd64_sources) cpu-amd64.md           \
index ebab8ae4b25519a818acf6fc04a10b53de9004c8..82e3672ae1dee2f7b56abf3141204e2d2dbe844c 100644 (file)
@@ -191,7 +191,9 @@ handle_instruction:
                        case OP_LOADU4_MEMBASE:
                        case OP_LOADI1_MEMBASE:
                        case OP_LOADI8_MEMBASE:
+#ifndef MONO_ARCH_SOFT_FLOAT_FALLBACK
                        case OP_LOADR4_MEMBASE:
+#endif
                        case OP_LOADR8_MEMBASE:
                                if (ins->inst_offset != 0)
                                        continue;
@@ -211,7 +213,9 @@ handle_instruction:
                        case OP_STOREI2_MEMBASE_REG:
                        case OP_STOREI4_MEMBASE_REG:
                        case OP_STOREI8_MEMBASE_REG:
+#ifndef MONO_ARCH_SOFT_FLOAT_FALLBACK
                        case OP_STORER4_MEMBASE_REG:
+#endif
                        case OP_STORER8_MEMBASE_REG:
                        case OP_STOREV_MEMBASE:
                                if (ins->inst_offset != 0)
index dba952c9ff1763d8926082130c5f10e4827e0a0e..34614773907bd8c6818564cc7b2d2aead45f5cf3 100644 (file)
@@ -9964,7 +9964,7 @@ compile_asm (MonoAotCompile *acfg)
                wrap_path (g_strdup_printf ("%s.o", acfg->tmpfname)), ld_flags);
 #else
        // Default (linux)
-       char *args = g_strdup_printf ("%s %s -shared -o %s %s %s %s", tool_prefix, LD_OPTIONS,
+       char *args = g_strdup_printf ("%s -shared -o %s %s %s %s", LD_OPTIONS,
                wrap_path (tmp_outfile_name), wrap_path (llvm_ofile),
                wrap_path (g_strdup_printf ("%s.o", acfg->tmpfname)), ld_flags);
 
@@ -10432,6 +10432,10 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options)
 #ifndef MONO_ARCH_GSHAREDVT_SUPPORTED
                aot_printerrf (acfg, "--aot=llvmonly requires a runtime that supports gsharedvt.\n");
                return 1;
+#endif
+#ifndef ENABLE_LLVM
+               aot_printerrf (acfg, "--aot=llvmonly requires a runtime compiled with llvm support.\n");
+               return 1;
 #endif
        }
 
index afa3a7dd0af38706cfa39638829ec6a420e9fc0b..e1849862a847f604f88fb5d933a2637796ee209c 100644 (file)
@@ -3908,7 +3908,8 @@ load_method (MonoDomain *domain, MonoAotModule *amodule, MonoImage *image, MonoM
                }
        }
 
-       if (!(is_llvm_code (amodule, code) && (amodule->info.flags & MONO_AOT_FILE_FLAG_LLVM_ONLY))) {
+       if (!(is_llvm_code (amodule, code) && (amodule->info.flags & MONO_AOT_FILE_FLAG_LLVM_ONLY)) ||
+               (mono_llvm_only && method && method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED)) {
                res = init_method (amodule, method_index, method, NULL, NULL, error);
                if (!res)
                        goto cleanup;
index a8eea0965d54bb34f9263672de5063974c378e48..7700619d2e9a316159bf9ee1dfe8342b70e15ac6 100644 (file)
@@ -459,26 +459,26 @@ atomic_exchange_i8: dest:i src1:i src2:i len:32
 atomic_cas_i4: dest:i src1:i src2:i src3:i len:32
 atomic_cas_i8: dest:i src1:i src2:i src3:i len:32
 memory_barrier: len:8 clob:a
-atomic_load_i1: dest:i src1:b len:20
-atomic_load_u1: dest:i src1:b len:20
-atomic_load_i2: dest:i src1:b len:20
-atomic_load_u2: dest:i src1:b len:20
-atomic_load_i4: dest:i src1:b len:16
-atomic_load_u4: dest:i src1:b len:16
-atomic_load_i8: dest:i src1:b len:12
-atomic_load_u8: dest:i src1:b len:12
-atomic_load_r4: dest:f src1:b len:24
-atomic_load_r8: dest:f src1:b len:20
-atomic_store_i1: dest:b src1:i len:16
-atomic_store_u1: dest:b src1:i len:16
-atomic_store_i2: dest:b src1:i len:16
-atomic_store_u2: dest:b src1:i len:16
-atomic_store_i4: dest:b src1:i len:16
-atomic_store_u4: dest:b src1:i len:16
-atomic_store_i8: dest:b src1:i len:12
-atomic_store_u8: dest:b src1:i len:12
-atomic_store_r4: dest:b src1:f len:24
-atomic_store_r8: dest:b src1:f len:20
+atomic_load_i1: dest:i src1:b len:24
+atomic_load_u1: dest:i src1:b len:24
+atomic_load_i2: dest:i src1:b len:24
+atomic_load_u2: dest:i src1:b len:24
+atomic_load_i4: dest:i src1:b len:24
+atomic_load_u4: dest:i src1:b len:24
+atomic_load_i8: dest:i src1:b len:20
+atomic_load_u8: dest:i src1:b len:20
+atomic_load_r4: dest:f src1:b len:28
+atomic_load_r8: dest:f src1:b len:24
+atomic_store_i1: dest:b src1:i len:20
+atomic_store_u1: dest:b src1:i len:20
+atomic_store_i2: dest:b src1:i len:20
+atomic_store_u2: dest:b src1:i len:20
+atomic_store_i4: dest:b src1:i len:20
+atomic_store_u4: dest:b src1:i len:20
+atomic_store_i8: dest:b src1:i len:20
+atomic_store_u8: dest:b src1:i len:20
+atomic_store_r4: dest:b src1:f len:28
+atomic_store_r8: dest:b src1:f len:24
 
 generic_class_init: src1:a len:44 clob:c
 gc_safe_point: src1:i len:12 clob:c
index ed3bee869a155630c8b1f6256d273db39a8487ff..22f063c59640e9253d58be382839db3c838575e7 100644 (file)
@@ -9833,16 +9833,17 @@ debugger_thread (void *arg)
        thread->internal_thread->state |= ThreadState_Background;
        thread->internal_thread->flags |= MONO_THREAD_FLAG_DONT_MANAGE;
 
-       mono_set_is_debugger_attached (TRUE);
-       
        if (agent_config.defer) {
                if (!wait_for_attach ()) {
                        DEBUG_PRINTF (1, "[dbg] Can't attach, aborting debugger thread.\n");
                        attach_failed = TRUE; // Don't abort process when we can't listen
                } else {
+                       mono_set_is_debugger_attached (TRUE);
                        /* Send start event to client */
                        process_profiler_event (EVENT_KIND_VM_START, mono_thread_get_main ());
                }
+       } else {
+               mono_set_is_debugger_attached (TRUE);
        }
        
        while (!attach_failed) {
index 0409cd7d78d0b20f7c73f59982a985442802ecfa..a883e70ee8915fc5301082d289ab5e15c3a412d0 100644 (file)
@@ -1889,6 +1889,13 @@ mono_local_emulate_ops (MonoCompile *cfg)
                        int op_noimm = mono_op_imm_to_op (ins->opcode);
                        MonoJitICallInfo *info;
 
+                       /*
+                        * These opcodes don't have logical equivalence to the emulating native
+                        * function. They are decomposed in specific fashion in mono_decompose_soft_float.
+                        */
+                       if (MONO_HAS_CUSTOM_EMULATION (ins))
+                               continue;
+
                        /*
                         * Emulation can't handle _IMM ops. If this is an imm opcode we need
                         * to check whether its non-imm counterpart is emulated and, if so,
index 9181e53b25257183de08774b3a793327ebe33be2..bd6e19fc4f50a07f60071c1ecd484b9cd3db2a60 100644 (file)
@@ -52,6 +52,7 @@
 #include "mono/utils/mono-counters.h"
 #include "mono/utils/mono-hwcap.h"
 #include "mono/utils/mono-logger-internals.h"
+#include "mono/utils/w32handle.h"
 
 #include "mini.h"
 #include "jit.h"
@@ -1367,30 +1368,6 @@ static const char info[] =
 #define error_if_aot_unsupported()
 #endif
 
-#ifdef HOST_WIN32
-BOOL APIENTRY DllMain (HMODULE module_handle, DWORD reason, LPVOID reserved)
-{
-       if (!mono_gc_dllmain (module_handle, reason, reserved))
-               return FALSE;
-
-       switch (reason)
-       {
-       case DLL_PROCESS_ATTACH:
-               mono_install_runtime_load (mini_init);
-               break;
-       case DLL_PROCESS_DETACH:
-               if (coree_module_handle)
-                       FreeLibrary (coree_module_handle);
-               break;
-       case DLL_THREAD_DETACH:
-               mono_thread_info_detach ();
-               break;
-       
-       }
-       return TRUE;
-}
-#endif
-
 static gboolean enable_debugging;
 
 /*
@@ -1986,6 +1963,10 @@ mono_main (int argc, char* argv[])
 
        mono_counters_init ();
 
+#ifndef HOST_WIN32
+       mono_w32handle_init ();
+#endif
+
        /* Set rootdir before loading config */
        mono_set_rootdir ();
 
diff --git a/mono/mini/emitnunit.pl b/mono/mini/emitnunit.pl
deleted file mode 100755 (executable)
index 63e6679..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Cwd;
-use POSIX qw(strftime uname locale_h);
-use Net::Domain qw(hostname hostfqdn);
-use locale;
-
-my $line;
-foreach $line (<STDIN>) {
-    chomp ($line);
-    print "$line\n";
-    if ($line =~ /^Overall results:/) {
-        # do magic nunit emission here
-        # failures look like:
-        #    Overall results: tests: 19992, failed: 48, opt combinations: 24 (pass: 99.76%)
-        # passes look like:
-        #    Overall results: tests: 20928, 100% pass, opt combinations: 24
-        my @words = split (/ /, $line);
-        my $failed;
-        my $successbool;
-        my $total = $words[3];
-        my $mylocale = setlocale (LC_CTYPE);
-        $mylocale = substr($mylocale, 0, index($mylocale, '.'));
-        $mylocale =~ s/_/-/;
-        if ($line =~ /failed:/) {
-            $failed = $words[5];
-        } else {
-            $failed = "0,";
-        }
-        chop ($failed);
-        chop ($total);
-        if ($failed > 0) {
-            $successbool = "False";
-        } else {
-            $successbool = "True";
-        }
-        open (my $nunitxml, '>', 'TestResult-regression.xml') or die "Could not write to 'TestResult-regression.xml' $!";
-        print $nunitxml "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n";
-        print $nunitxml "<!--This file represents the results of running a test suite-->\n";
-        print $nunitxml "<test-results name=\"regression-tests.dummy\" total=\"$total\" failures=\"$failed\" not-run=\"0\" date=\"" . strftime ("%F", localtime) . "\" time=\"" . strftime ("%T", localtime) . "\">\n";
-        print $nunitxml "  <environment nunit-version=\"2.4.8.0\" clr-version=\"4.0.30319.17020\" os-version=\"Unix " . (uname ())[2]  . "\" platform=\"Unix\" cwd=\"" . getcwd . "\" machine-name=\"" . hostname . "\" user=\"" . getpwuid ($<) . "\" user-domain=\"" . hostfqdn  . "\" />\n";
-        print $nunitxml "  <culture-info current-culture=\"$mylocale\" current-uiculture=\"$mylocale\" />\n";
-        print $nunitxml "  <test-suite name=\"regression-tests.dummy\" success=\"$successbool\" time=\"0\" asserts=\"0\">\n";
-        print $nunitxml "    <results>\n";
-        print $nunitxml "      <test-suite name=\"MonoTests\" success=\"$successbool\" time=\"0\" asserts=\"0\">\n";
-        print $nunitxml "        <results>\n";
-        print $nunitxml "          <test-suite name=\"regressions\" success=\"$successbool\" time=\"0\" asserts=\"0\">\n";
-        print $nunitxml "            <results>\n";
-        print $nunitxml "              <test-case name=\"MonoTests.regressions.100percentsuccess\" executed=\"True\" success=\"$successbool\" time=\"0\" asserts=\"0\"";
-        if ( $failed > 0) {
-        print $nunitxml ">\n";
-        print $nunitxml "                <failure>\n";
-        print $nunitxml "                  <message><![CDATA[";
-        foreach $line (<STDIN>) {
-            chomp ($line);
-            print "$line\n";
-        }
-        print $nunitxml "]]></message>\n";
-        print $nunitxml "                  <stack-trace>\n";
-        print $nunitxml "                  </stack-trace>\n";
-        print $nunitxml "                </failure>\n";
-        print $nunitxml "              </test-case>\n";
-        } else {
-        print $nunitxml " />\n";
-        }
-        print $nunitxml "            </results>\n";
-        print $nunitxml "          </test-suite>\n";
-        print $nunitxml "        </results>\n";
-        print $nunitxml "      </test-suite>\n";
-        print $nunitxml "    </results>\n";
-        print $nunitxml "  </test-suite>\n";
-        print $nunitxml "</test-results>\n";
-        close $nunitxml;
-    }
-}
index d7c6d9a232fe63bbbf3731b6bd6567f2caf676eb..f8a328375b90de9bdc0344ff7e26192e50b46dc0 100644 (file)
@@ -1924,3 +1924,8 @@ mono_throw_method_access (MonoMethod *callee, MonoMethod *caller)
        g_free (callee_name);
        g_free (caller_name);
 }
+
+void
+mono_dummy_jit_icall (void)
+{
+}
index 319ec902a013c47aaac095493c859aee047d2149..9d8deb26198c77832464ab704408e37ec51115cf 100644 (file)
@@ -226,4 +226,6 @@ double mono_ckfinite (double d);
 
 void mono_throw_method_access (MonoMethod *callee, MonoMethod *caller);
 
+void mono_dummy_jit_icall (void);
+
 #endif /* __MONO_JIT_ICALLS_H__ */
index bc57ec67f9219aeb4dac3df784fb37820d4d931b..04373359fb46ead9bc1ea8d96249d33ee4c15948 100644 (file)
@@ -362,7 +362,8 @@ mono_strength_reduction_ins (MonoCompile *cfg, MonoInst *ins, const char **spec)
        }
        case OP_IDIV_UN_IMM:
        case OP_IDIV_IMM: {
-               allocated_vregs = mono_strength_reduction_division (cfg, ins);
+               if (!COMPILE_LLVM (cfg))
+                       allocated_vregs = mono_strength_reduction_division (cfg, ins);
                break;
        }
 #if SIZEOF_REGISTER == 8
index 1f9ffcf5d467b12f6b2ad89fdeadc57725db4b7d..8d2f5bd17121d78ef98c4fba3c8e1f427d4b86da 100644 (file)
@@ -1,6 +1,7 @@
 #include <config.h>
 #include <fcntl.h>
 #include <mono/metadata/assembly.h>
+#include <mono/metadata/mono-config.h>
 #include <mono/utils/mono-mmap.h>
 #include "mini.h"
 
@@ -28,8 +29,40 @@ mono_main_with_options (int argc, char *argv [])
        return mono_main (argc, argv);
 }
 
-#define STREAM_INT(x) (*(uint32_t*)x)
-#define STREAM_LONG(x) (*(uint64_t*)x)
+#define STREAM_INT(x) GUINT32_TO_LE((*(uint32_t*)x))
+#define STREAM_LONG(x) GUINT64_TO_LE((*(uint64_t*)x))
+
+/**
+ * Loads a chunk of data from the file pointed to by the
+ * @fd starting at the file offset @offset for @size bytes
+ * and returns an allocated version of that string, or NULL
+ * on error.
+ */
+static char *
+load_from_region (int fd, uint64_t offset, uint64_t size)
+{
+       char *buffer;
+       off_t loc;
+       int status;
+       
+       do {
+               loc = lseek (fd, offset, SEEK_SET);
+       } while (loc == -1 && errno == EINTR);
+       if (loc == -1)
+               return NULL;
+       buffer = g_malloc (size + 1);
+       if (buffer == NULL)
+               return NULL;
+       buffer [size] = 0;
+       do {
+               status = read (fd, buffer, size);
+       } while (status == -1 && errno == EINTR);
+       if (status == -1){
+               g_free (buffer);
+               return NULL;
+       }
+       return buffer;
+}
 
 static gboolean
 probe_embedded (const char *program, int *ref_argc, char **ref_argv [])
@@ -103,13 +136,20 @@ probe_embedded (const char *program, int *ref_argc, char **ref_argv [])
                        char *config = kind + strlen ("config:");
                        char *aname = g_strdup (config);
                        aname [strlen(aname)-strlen(".config")] = 0;
-                       mono_register_config_for_assembly (aname, config);
-               } else if (strncmp (kind, "system_config:", strlen ("system_config:")) == 0){
-                       printf ("TODO s-Found: %s %llx\n", kind, (long long)offset);
+                       mono_register_config_for_assembly (aname, load_from_region (fd, offset, item_size));
+               } else if (strncmp (kind, "systemconfig:", strlen ("systemconfig:")) == 0){
+                       mono_config_parse_memory (load_from_region (fd, offset, item_size));
                } else if (strncmp (kind, "options:", strlen ("options:")) == 0){
-                       mono_parse_options_from (kind + strlen("options:"), ref_argc, ref_argv);
+                       mono_parse_options_from (load_from_region (fd, offset, item_size), ref_argc, ref_argv);
                } else if (strncmp (kind, "config_dir:", strlen ("config_dir:")) == 0){
-                       printf ("TODO Found: %s %llx\n", kind, (long long)offset);
+                       mono_set_dirs (getenv ("MONO_PATH"), load_from_region (fd, offset, item_size));
+               } else if (strncmp (kind, "machineconfig:", strlen ("machineconfig:")) == 0) {
+                       mono_register_machine_config (load_from_region (fd, offset, item_size));
+               } else if (strncmp (kind, "env:", strlen ("env:")) == 0){
+                       char *data = load_from_region (fd, offset, item_size);
+                       uint8_t count = *data++;
+                       char *value = data + count + 1;
+                       g_setenv (data, value, FALSE);
                } else {
                        fprintf (stderr, "Unknown stream on embedded package: %s\n", kind);
                        exit (1);
index 386a319cc50234118d4e32d940a370c1d0833609..6769d9c5f85fd622df4f250c8e865e678eef8fb8 100644 (file)
@@ -4486,6 +4486,16 @@ icall_is_direct_callable (MonoCompile *cfg, MonoMethod *cmethod)
        return FALSE;
 }
 
+static gboolean
+method_needs_stack_walk (MonoCompile *cfg, MonoMethod *cmethod)
+{
+       if (cmethod->klass == mono_defaults.systemtype_class) {
+               if (!strcmp (cmethod->name, "GetType"))
+                       return TRUE;
+       }
+       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)
 
 static MonoInst*
@@ -9732,6 +9742,10 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                }
 
                                if (!has_vtargs) {
+                                       if (need_seq_point) {
+                                               emit_seq_point (cfg, method, ip, FALSE, TRUE);
+                                               need_seq_point = FALSE;
+                                       }
                                        for (i = 0; i < n; ++i)
                                                EMIT_NEW_ARGSTORE (cfg, ins, i, sp [i]);
                                        MONO_INST_NEW (cfg, ins, OP_BR);
@@ -10032,6 +10046,16 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                EMIT_NEW_DUMMY_USE (cfg, dummy_use, keep_this_alive);
                        }
 
+                       if (cfg->llvm_only && cmethod && method_needs_stack_walk (cfg, cmethod)) {
+                               /*
+                                * Clang can convert these calls to tail calls which screw up the stack
+                                * walk. This happens even when the -fno-optimize-sibling-calls
+                                * option is passed to clang.
+                                * Work around this by emitting a dummy call.
+                                */
+                               mono_emit_jit_icall (cfg, mono_dummy_jit_icall, NULL);
+                       }
+
                        CHECK_CFG_EXCEPTION;
 
                        ip += 5;
index 258b265e063cc4f986c7e5b5a7c9bfa47a1e82af..f9a0d5adc8bdfa90c778cbc613c58ecf6d0f4fc0 100644 (file)
@@ -33,7 +33,7 @@
 #include <mono/utils/mono-mmap.h>
 #include <mono/utils/mono-memory-model.h>
 #include <mono/utils/mono-tls.h>
-#include <mono/utils/mono-hwcap-x86.h>
+#include <mono/utils/mono-hwcap.h>
 #include <mono/utils/mono-threads.h>
 
 #include "trace.h"
@@ -402,6 +402,10 @@ collect_field_info_nested (MonoClass *klass, StructFieldInfo *fields, int index,
                                                                                                                           info->fields [i].mspec,
                                                                                                                           &align, TRUE, unicode);
                                fields [index].offset = offset + info->fields [i].offset;
+                               if (i == info->num_fields - 1 && fields [index].size + fields [index].offset < info->native_size) {
+                                       /* This can happen with .pack directives eg. 'fixed' arrays */
+                                       fields [index].size = info->native_size - fields [index].offset;
+                               }
                                index ++;
                        }
                }
index 6983398027a5b2bb2e37143c455dceb3db0635cc..7b2e1fa7b48e2438c7e85deeb87108be375a6936 100644 (file)
@@ -18,7 +18,7 @@
 #include <mono/metadata/profiler-private.h>
 #include <mono/metadata/debug-helpers.h>
 #include <mono/utils/mono-mmap.h>
-#include <mono/utils/mono-hwcap-arm.h>
+#include <mono/utils/mono-hwcap.h>
 #include <mono/utils/mono-memory-model.h>
 #include <mono/utils/mono-threads-coop.h>
 
index d16cee8cee3daa00962ced9e1ed97a12959fc445..2a437730a73b5d0e4057ec4f461a1bdefe98de4b 100644 (file)
@@ -94,6 +94,7 @@ static void restore_stack_protection (void);
 static void mono_walk_stack_full (MonoJitStackWalk func, MonoContext *start_ctx, MonoDomain *domain, MonoJitTlsData *jit_tls, MonoLMF *lmf, MonoUnwindOptions unwind_options, gpointer user_data);
 static void mono_raise_exception_with_ctx (MonoException *exc, MonoContext *ctx);
 static void mono_runtime_walk_stack_with_ctx (MonoJitStackWalk func, MonoContext *start_ctx, MonoUnwindOptions unwind_options, void *user_data);
+static gboolean mono_current_thread_has_handle_block_guard (void);
 
 void
 mono_exceptions_init (void)
@@ -136,6 +137,7 @@ mono_exceptions_init (void)
        cbs.mono_raise_exception_with_ctx = mono_raise_exception_with_ctx;
        cbs.mono_exception_walk_trace = mono_exception_walk_trace;
        cbs.mono_install_handler_block_guard = mono_install_handler_block_guard;
+       cbs.mono_current_thread_has_handle_block_guard = mono_current_thread_has_handle_block_guard;
        mono_install_eh_callbacks (&cbs);
 }
 
@@ -2676,6 +2678,13 @@ mono_install_handler_block_guard (MonoThreadUnwindState *ctx)
        return TRUE;
 }
 
+static gboolean
+mono_current_thread_has_handle_block_guard (void)
+{
+       MonoJitTlsData *jit_tls = (MonoJitTlsData *)mono_native_tls_get_value (mono_jit_tls_id);
+       return jit_tls && jit_tls->handler_block_return_address != NULL;
+}
+
 #else
 gboolean
 mono_install_handler_block_guard (MonoThreadUnwindState *ctx)
@@ -2683,6 +2692,12 @@ mono_install_handler_block_guard (MonoThreadUnwindState *ctx)
        return FALSE;
 }
 
+static gboolean
+mono_current_thread_has_handle_block_guard (void)
+{
+       return FALSE;
+}
+
 #endif
 
 void
index d88a6c99a8f362bb690424ace4462d58f3d913d9..357e260799833ed8d4a1bf415c148853bf610e39 100644 (file)
@@ -21,7 +21,7 @@
 #include <mono/metadata/threads.h>
 #include <mono/metadata/profiler-private.h>
 #include <mono/utils/mono-math.h>
-#include <mono/utils/mono-hwcap-ia64.h>
+#include <mono/utils/mono-hwcap.h>
 
 #include "trace.h"
 #include "mini-ia64.h"
index 61f3730f520383cefbc8fb9fc89b5d279f097cf4..3ca1bca04c16a83087b5b01bf5c6eba63f020576 100644 (file)
@@ -5375,6 +5375,17 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                        values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
                        break;
                }
+
+/*
+ * See the ARM64 comment in mono/utils/atomic.h for an explanation of why this
+ * hack is necessary (for now).
+ */
+#ifdef TARGET_ARM64
+#define ARM64_ATOMIC_FENCE_FIX mono_llvm_build_fence (builder, LLVM_BARRIER_SEQ)
+#else
+#define ARM64_ATOMIC_FENCE_FIX
+#endif
+
                case OP_ATOMIC_EXCHANGE_I4:
                case OP_ATOMIC_EXCHANGE_I8: {
                        LLVMValueRef args [2];
@@ -5390,7 +5401,9 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                        args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
                        args [1] = convert (ctx, rhs, t);
 
+                       ARM64_ATOMIC_FENCE_FIX;
                        values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
+                       ARM64_ATOMIC_FENCE_FIX;
                        break;
                }
                case OP_ATOMIC_ADD_I4:
@@ -5407,7 +5420,9 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
 
                        args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
                        args [1] = convert (ctx, rhs, t);
+                       ARM64_ATOMIC_FENCE_FIX;
                        values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
+                       ARM64_ATOMIC_FENCE_FIX;
                        break;
                }
                case OP_ATOMIC_CAS_I4:
@@ -5425,7 +5440,9 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                        args [1] = convert (ctx, values [ins->sreg3], t);
                        /* new value */
                        args [2] = convert (ctx, values [ins->sreg2], t);
+                       ARM64_ATOMIC_FENCE_FIX;
                        val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
+                       ARM64_ATOMIC_FENCE_FIX;
                        /* cmpxchg returns a pair */
                        values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
                        break;
@@ -5466,7 +5483,9 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
 
                        addr = convert (ctx, addr, LLVMPointerType (t, 0));
 
+                       ARM64_ATOMIC_FENCE_FIX;
                        values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, lhs, dname, is_volatile, barrier);
+                       ARM64_ATOMIC_FENCE_FIX;
 
                        if (sext)
                                values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
@@ -5514,7 +5533,9 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                        addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
                        value = convert (ctx, values [ins->sreg1], t);
 
+                       ARM64_ATOMIC_FENCE_FIX;
                        emit_store_general (ctx, bb, &builder, size, value, addr, base, is_volatile, barrier);
+                       ARM64_ATOMIC_FENCE_FIX;
                        break;
                }
                case OP_RELAXED_NOP: {
@@ -7241,7 +7262,11 @@ emit_method_inner (EmitContext *ctx)
                ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
 
                // FIXME: beforefieldinit
-               if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
+               /*
+                * NATIVE_TO_MANAGED methods might be called on a thread not attached to the runtime, so they are initialized when loaded
+                * in load_method ().
+                */
+               if ((ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) && !(cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED)) {
                        /*
                         * linkonce methods shouldn't have initialization,
                         * because they might belong to assemblies which
index 5d6ebc7b6bc126975df54bdc38c29d247d5ca8d0..783896f15681743acb6001dad302705db271bee9 100644 (file)
@@ -19,7 +19,7 @@
 #include <mono/metadata/appdomain.h>
 #include <mono/metadata/debug-helpers.h>
 #include <mono/utils/mono-mmap.h>
-#include <mono/utils/mono-hwcap-mips.h>
+#include <mono/utils/mono-hwcap.h>
 
 #include <mono/arch/mips/mips-codegen.h>
 
index 5d66853ece98745dcfe334f57c49d357517159d9..6e461b806b461d133a7ecd56912a48c49d441354 100644 (file)
@@ -406,6 +406,13 @@ mono_class_is_magic_float (MonoClass *klass)
 
        if (strcmp ("nfloat", klass->name) == 0) {
                magic_nfloat_class = klass;
+
+               /* Assert that we are using the matching assembly */
+               MonoClassField *value_field = mono_class_get_field_from_name (klass, "v");
+               g_assert (value_field);
+               MonoType *t = mono_field_get_type (value_field);
+               g_assert (t->type == mini_native_type_replace_type (&klass->byval_arg)->type);
+
                return TRUE;
        }
        return FALSE;
index 3089a8546b1d3a4d605535a775c1f57d27eb793f..7d2c0d8b8cfda73cacd3b6847b37f7c5dd523da4 100644 (file)
@@ -17,7 +17,7 @@
 #include <mono/metadata/debug-helpers.h>
 #include <mono/utils/mono-proclib.h>
 #include <mono/utils/mono-mmap.h>
-#include <mono/utils/mono-hwcap-ppc.h>
+#include <mono/utils/mono-hwcap.h>
 
 #include "mini-ppc.h"
 #ifdef TARGET_POWERPC64
index 857f52ea70ba7353ffbd0ab1a32b6225d63fc87a..f4f30c69e6ba02fb18ddc33d4b0c2e580d4d541b 100644 (file)
@@ -65,6 +65,7 @@
 #include <mono/utils/mono-threads.h>
 #include <mono/utils/mono-threads-coop.h>
 #include <mono/utils/checked-build.h>
+#include <mono/utils/w32handle.h>
 #include <mono/io-layer/io-layer.h>
 
 #include "mini.h"
@@ -2355,10 +2356,8 @@ mono_llvmonly_runtime_invoke (MonoMethod *method, RuntimeInvokeInfo *info, void
        runtime_invoke = (MonoObject *(*)(MonoObject *, void **, MonoObject **, void *))info->runtime_invoke;
 
        runtime_invoke (NULL, args, exc, info->compiled_method);
-       if (exc && *exc) {
-               mono_error_set_exception_instance (error, (MonoException*) *exc);
+       if (exc && *exc)
                return NULL;
-       }
 
        if (sig->ret->type != MONO_TYPE_VOID && info->ret_box_class)
                return mono_value_box_checked (domain, info->ret_box_class, retval, error);
@@ -2544,12 +2543,17 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
        }
 #endif
 
-       if (mono_llvm_only)
-               return mono_llvmonly_runtime_invoke (method, info, obj, params, exc, error);
+       MonoObject *result;
 
-       runtime_invoke = (MonoObject *(*)(MonoObject *, void **, MonoObject **, void *))info->runtime_invoke;
+       if (mono_llvm_only) {
+               result = mono_llvmonly_runtime_invoke (method, info, obj, params, exc, error);
+               if (!is_ok (error))
+                       return NULL;
+       } else {
+               runtime_invoke = (MonoObject *(*)(MonoObject *, void **, MonoObject **, void *))info->runtime_invoke;
 
-       MonoObject *result = runtime_invoke ((MonoObject *)obj, params, exc, info->compiled_method);
+               result = runtime_invoke ((MonoObject *)obj, params, exc, info->compiled_method);
+       }
        if (catchExcInMonoError && *exc != NULL)
                mono_error_set_exception_instance (error, (MonoException*) *exc);
        return result;
@@ -3569,6 +3573,10 @@ mini_init (const char *filename, const char *runtime_version)
 
        mono_counters_init ();
 
+#ifndef HOST_WIN32
+       mono_w32handle_init ();
+#endif
+
        mono_threads_runtime_init (&ticallbacks);
 
        if (g_getenv ("MONO_DEBUG") != NULL)
@@ -3975,6 +3983,7 @@ register_icalls (void)
        register_icall (mono_get_assembly_object, "mono_get_assembly_object", "object ptr", TRUE);
        register_icall (mono_get_method_object, "mono_get_method_object", "object ptr", TRUE);
        register_icall (mono_throw_method_access, "mono_throw_method_access", "void ptr ptr", FALSE);
+       register_icall_no_wrapper (mono_dummy_jit_icall, "mono_dummy_jit_icall", "void");
 
        register_icall_with_wrapper (mono_monitor_enter, "mono_monitor_enter", "void obj");
        register_icall_with_wrapper (mono_monitor_enter_v4, "mono_monitor_enter_v4", "void obj ptr");
@@ -4109,6 +4118,10 @@ mini_cleanup (MonoDomain *domain)
        mono_os_mutex_destroy (&jit_mutex);
 
        mono_code_manager_cleanup ();
+
+#ifndef HOST_WIN32
+       mono_w32handle_cleanup ();
+#endif
 }
 
 void
index 3fe40d2cfc28fdd8a055b003ad58785d5cbd3427..a1094afa173fbe0baeb75c2ff221e0e9b73ae7e9 100644 (file)
@@ -268,7 +268,7 @@ if (ins->inst_target_bb->native_offset) {                                   \
 #include <mono/utils/mono-error-internals.h>
 #include <mono/utils/mono-math.h>
 #include <mono/utils/mono-mmap.h>
-#include <mono/utils/mono-hwcap-s390x.h>
+#include <mono/utils/mono-hwcap.h>
 #include <mono/utils/mono-threads.h>
 
 #include "mini-s390x.h"
@@ -399,8 +399,6 @@ pthread_key_t lmf_addr_key;
 
 gboolean lmf_addr_key_inited = FALSE; 
 
-facilityList_t facs;
-
 /*
  * The code generated for sequence points reads from this location, 
  * which is made read-only when single stepping is enabled.
@@ -4370,7 +4368,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                }
                        break;
                case OP_ICONV_TO_R_UN: {
-                       if (facs.fpe) {
+                       if (mono_hwcap_s390x_has_fpe) {
                                s390_cdlfbr (code, ins->dreg, 5, ins->sreg1, 0);
                        } else {
                                s390_llgfr (code, s390_r0, ins->sreg1);
@@ -4379,7 +4377,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                }
                        break;
                case OP_LCONV_TO_R_UN: {
-                       if (facs.fpe) {
+                       if (mono_hwcap_s390x_has_fpe) {
                                s390_cdlgbr (code, ins->dreg, 5, ins->sreg1, 0);
                        } else {
                                short int *jump;
@@ -4416,7 +4414,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        s390_ngr   (code, ins->dreg, s390_r0);
                        break;
                case OP_FCONV_TO_U1:
-                       if (facs.fpe) {
+                       if (mono_hwcap_s390x_has_fpe) {
                                s390_clgdbr (code, ins->dreg, 5, ins->sreg1, 0);
                                s390_lghi  (code, s390_r0, 0xff);
                                s390_ngr   (code, ins->dreg, s390_r0);
@@ -4433,7 +4431,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        s390_ngr   (code, ins->dreg, s390_r0);
                        break;
                case OP_FCONV_TO_U2:
-                       if (facs.fpe) {
+                       if (mono_hwcap_s390x_has_fpe) {
                                s390_clgdbr (code, ins->dreg, 5, ins->sreg1, 0);
                                s390_llill  (code, s390_r0, 0xffff);
                                s390_ngr    (code, ins->dreg, s390_r0);
@@ -4447,7 +4445,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        break;
                case OP_FCONV_TO_U4:
                case OP_FCONV_TO_U:
-                       if (facs.fpe) {
+                       if (mono_hwcap_s390x_has_fpe) {
                                s390_clfdbr (code, ins->dreg, 5, ins->sreg1, 0);
                        } else {
                                code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 4, FALSE);
@@ -4457,7 +4455,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        s390_cgdbr (code, ins->dreg, 5, ins->sreg1);
                        break;
                case OP_FCONV_TO_U8:
-                       if (facs.fpe) {
+                       if (mono_hwcap_s390x_has_fpe) {
                                s390_clgdbr (code, ins->dreg, 5, ins->sreg1, 0);
                        } else {
                                code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 8, FALSE);
@@ -7077,7 +7075,7 @@ mono_arch_cpu_enumerate_simd_versions (void)
 {
        guint32 sseOpts = 0;
 
-       if (facs.vec != 0) 
+       if (mono_hwcap_s390x_has_vec)
                sseOpts = (SIMD_VERSION_SSE1  | SIMD_VERSION_SSE2 |
                           SIMD_VERSION_SSE3  | SIMD_VERSION_SSSE3 |
                           SIMD_VERSION_SSE41 | SIMD_VERSION_SSE42 |
index 022f8a5e790b8ea9334d4fa61bb7f92c99229c9f..5003bfe025403fa2d02c9709b18d04fa2e26b491 100644 (file)
@@ -28,7 +28,7 @@
 #include <mono/metadata/debug-helpers.h>
 #include <mono/metadata/tokentype.h>
 #include <mono/utils/mono-math.h>
-#include <mono/utils/mono-hwcap-sparc.h>
+#include <mono/utils/mono-hwcap.h>
 
 #include "mini-sparc.h"
 #include "trace.h"
diff --git a/mono/mini/mini-windows-dllmain.c b/mono/mini/mini-windows-dllmain.c
new file mode 100644 (file)
index 0000000..887a6a1
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * mini-windows-dllmain.c: DllMain entry point.
+ *
+ * (C) 2002-2003 Ximian, Inc.
+ * (C) 2003-2006 Novell, Inc.
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+
+#include <mono/metadata/coree.h>
+#include <mono/metadata/gc-internals.h>
+#include <mono/metadata/domain-internals.h>
+#include <mono/utils/mono-threads.h>
+#include "mini.h"
+
+#ifdef HOST_WIN32
+#include <windows.h>
+
+BOOL APIENTRY DllMain (HMODULE module_handle, DWORD reason, LPVOID reserved)
+{
+       if (!mono_gc_dllmain (module_handle, reason, reserved))
+               return FALSE;
+
+       switch (reason)
+       {
+       case DLL_PROCESS_ATTACH:
+               mono_install_runtime_load (mini_init);
+               break;
+       case DLL_PROCESS_DETACH:
+               if (coree_module_handle)
+                       FreeLibrary (coree_module_handle);
+               break;
+       case DLL_THREAD_DETACH:
+               mono_thread_info_detach ();
+               break;
+       
+       }
+       return TRUE;
+}
+#endif
+
index 9e1702be17c8e32286f5233e2423a4740d2b59ec..288af652434bf9ffc25e4ad0893d5087409de286 100644 (file)
@@ -29,7 +29,7 @@
 #include <mono/utils/mono-counters.h>
 #include <mono/utils/mono-mmap.h>
 #include <mono/utils/mono-memory-model.h>
-#include <mono/utils/mono-hwcap-x86.h>
+#include <mono/utils/mono-hwcap.h>
 #include <mono/utils/mono-threads.h>
 
 #include "trace.h"
index 2f0259cdcb2aff3a82f190daa8fbac1999892e64..845162f76f7349228657010d253c8dbfbae09b4f 100644 (file)
@@ -490,6 +490,7 @@ enum {
 
 #define MONO_IS_SETCC(ins) ((((ins)->opcode >= OP_CEQ) && ((ins)->opcode <= OP_CLT_UN)) || (((ins)->opcode >= OP_ICEQ) && ((ins)->opcode <= OP_ICLE_UN)) || (((ins)->opcode >= OP_LCEQ) && ((ins)->opcode <= OP_LCLT_UN)) || (((ins)->opcode >= OP_FCEQ) && ((ins)->opcode <= OP_FCLT_UN)))
 
+#define MONO_HAS_CUSTOM_EMULATION(ins) (((ins)->opcode >= OP_FBEQ && (ins)->opcode <= OP_FBLT_UN) || ((ins)->opcode >= OP_FCEQ && (ins)->opcode <= OP_FCLT_UN))
 
 #define MONO_IS_LOAD_MEMBASE(ins) (((ins)->opcode >= OP_LOAD_MEMBASE && (ins)->opcode <= OP_LOADV_MEMBASE) || ((ins)->opcode >= OP_ATOMIC_LOAD_I1 && (ins)->opcode <= OP_ATOMIC_LOAD_R8))
 #define MONO_IS_STORE_MEMBASE(ins) (((ins)->opcode >= OP_STORE_MEMBASE_REG && (ins)->opcode <= OP_STOREV_MEMBASE) || ((ins)->opcode >= OP_ATOMIC_STORE_I1 && (ins)->opcode <= OP_ATOMIC_STORE_R8))
index 02b1f12c08f2b5b74e669ece1bbd6e4ab7c43992..747163b176dc74678a91987d3b1046224ec8fd61 100644 (file)
@@ -876,13 +876,8 @@ mono_arch_get_call_target (guint8 *code)
 {
        guint32 ins = ((guint32*)(gpointer)code) [-1];
 
-#if MONOTOUCH
        /* Should be a 'bl' or a 'b' */
        if (((ins >> 25) & 0x7) == 0x5) {
-#else
-       /* Should be a 'bl' */
-       if ((((ins >> 25) & 0x7) == 0x5) && (((ins >> 24) & 0x1) == 0x1)) {
-#endif
                gint32 disp = ((((gint32)ins) & 0xffffff) << 8) >> 8;
                guint8 *target = code - 4 + 8 + (disp * 4);
 
index e8d53afea686ed76588370c99fe74beac2c0718b..b213528caaa35b55a02a43f0c8b2329a40eeab75 100644 (file)
@@ -1517,6 +1517,9 @@ typedef struct {
        int timer_overhead;
        int pid;
        int port;
+       char *args;
+       char *arch;
+       char *os;
        uint64_t startup_time;
        ThreadContext *threads;
        ThreadContext *current_thread;
@@ -1862,9 +1865,23 @@ gc_event_name (int ev)
        case MONO_GC_EVENT_RECLAIM_END: return "reclaim end";
        case MONO_GC_EVENT_END: return "end";
        case MONO_GC_EVENT_PRE_STOP_WORLD: return "pre stop";
+       case MONO_GC_EVENT_PRE_STOP_WORLD_LOCKED: return "pre stop lock";
        case MONO_GC_EVENT_POST_STOP_WORLD: return "post stop";
        case MONO_GC_EVENT_PRE_START_WORLD: return "pre start";
        case MONO_GC_EVENT_POST_START_WORLD: return "post start";
+       case MONO_GC_EVENT_POST_START_WORLD_UNLOCKED: return "post start unlock";
+       default:
+               return "unknown";
+       }
+}
+
+static const char*
+sync_point_name (int type)
+{
+       switch (type) {
+       case SYNC_POINT_PERIODIC: return "periodic";
+       case SYNC_POINT_WORLD_STOP: return "world stop";
+       case SYNC_POINT_WORLD_START: return "world start";
        default:
                return "unknown";
        }
@@ -1956,21 +1973,25 @@ get_root_name (int rtype)
 }
 
 static MethodDesc**
-decode_bt (MethodDesc** sframes, int *size, unsigned char *p, unsigned char **endp, intptr_t ptr_base)
+decode_bt (ProfContext *ctx, MethodDesc** sframes, int *size, unsigned char *p, unsigned char **endp, intptr_t ptr_base, intptr_t *method_base)
 {
        MethodDesc **frames;
        int i;
-       int flags = decode_uleb128 (p, &p);
+       if (ctx->data_version < 13)
+               decode_uleb128 (p, &p); /* flags */
        int count = decode_uleb128 (p, &p);
-       if (flags != 0)
-               return NULL;
        if (count > *size)
                frames = (MethodDesc **)malloc (count * sizeof (void*));
        else
                frames = sframes;
        for (i = 0; i < count; ++i) {
                intptr_t ptrdiff = decode_sleb128 (p, &p);
-               frames [i] = lookup_method (ptr_base + ptrdiff);
+               if (ctx->data_version > 12) {
+                       *method_base += ptrdiff;
+                       frames [i] = lookup_method (*method_base);
+               } else {
+                       frames [i] = lookup_method (ptr_base + ptrdiff);
+               }
        }
        *size = count;
        *endp = p;
@@ -2279,8 +2300,16 @@ decode_buffer (ProfContext *ctx)
                                if (new_size > max_heap_size)
                                        max_heap_size = new_size;
                        } else if (subtype == TYPE_GC_EVENT) {
-                               uint64_t ev = decode_uleb128 (p, &p);
-                               int gen = decode_uleb128 (p, &p);
+                               uint64_t ev;
+                               if (ctx->data_version > 12)
+                                       ev = *p++;
+                               else
+                                       ev = decode_uleb128 (p, &p);
+                               int gen;
+                               if (ctx->data_version > 12)
+                                       gen = *p++;
+                               else
+                                       gen = decode_uleb128 (p, &p);
                                if (debug)
                                        fprintf (outfile, "gc event for gen%d: %s at %llu (thread: 0x%zx)\n", gen, gc_event_name (ev), (unsigned long long) time_base, thread->thread_id);
                                if (gen > 2) {
@@ -2318,7 +2347,7 @@ decode_buffer (ProfContext *ctx)
                                intptr_t objdiff = decode_sleb128 (p, &p);
                                if (has_bt) {
                                        num_bt = 8;
-                                       frames = decode_bt (sframes, &num_bt, p, &p, ptr_base);
+                                       frames = decode_bt (ctx, sframes, &num_bt, p, &p, ptr_base, &method_base);
                                        if (!frames) {
                                                fprintf (outfile, "Cannot load backtrace\n");
                                                return 0;
@@ -2352,7 +2381,7 @@ decode_buffer (ProfContext *ctx)
                                uint32_t handle = decode_uleb128 (p, &p);
                                if (has_bt) {
                                        num_bt = 8;
-                                       frames = decode_bt (sframes, &num_bt, p, &p, ptr_base);
+                                       frames = decode_bt (ctx, sframes, &num_bt, p, &p, ptr_base, &method_base);
                                        if (!frames) {
                                                fprintf (outfile, "Cannot load backtrace\n");
                                                return 0;
@@ -2374,6 +2403,21 @@ decode_buffer (ProfContext *ctx)
                                        fprintf (outfile, "handle (%s) %u destroyed\n", get_handle_name (htype), handle);
                                if (frames != sframes)
                                        free (frames);
+                       } else if (subtype == TYPE_GC_FINALIZE_START) {
+                               // TODO: Generate a finalizer report based on these events.
+                               if (debug)
+                                       fprintf (outfile, "gc finalizer queue being processed at %llu\n", (unsigned long long) time_base);
+                       } else if (subtype == TYPE_GC_FINALIZE_END) {
+                               if (debug)
+                                       fprintf (outfile, "gc finalizer queue finished processing at %llu\n", (unsigned long long) time_base);
+                       } else if (subtype == TYPE_GC_FINALIZE_OBJECT_START) {
+                               intptr_t objdiff = decode_sleb128 (p, &p);
+                               if (debug)
+                                       fprintf (outfile, "gc finalizing object %p at %llu\n", (void *) OBJ_ADDR (objdiff), (unsigned long long) time_base);
+                       } else if (subtype == TYPE_GC_FINALIZE_OBJECT_END) {
+                               intptr_t objdiff = decode_sleb128 (p, &p);
+                               if (debug)
+                                       fprintf (outfile, "gc finalized object %p at %llu\n", (void *) OBJ_ADDR (objdiff), (unsigned long long) time_base);
                        }
                        break;
                }
@@ -2387,11 +2431,8 @@ decode_buffer (ProfContext *ctx)
                        time_base += tdiff;
                        if (mtype == TYPE_CLASS) {
                                intptr_t imptrdiff = decode_sleb128 (p, &p);
-                               uint64_t flags = decode_uleb128 (p, &p);
-                               if (flags) {
-                                       fprintf (outfile, "non-zero flags in class\n");
-                                       return 0;
-                               }
+                               if (ctx->data_version < 13)
+                                       decode_uleb128 (p, &p); /* flags */
                                if (debug)
                                        fprintf (outfile, "%s class %p (%s in %p) at %llu\n", load_str, (void*)(ptr_base + ptrdiff), p, (void*)(ptr_base + imptrdiff), (unsigned long long) time_base);
                                if (subtype == TYPE_END_LOAD)
@@ -2399,11 +2440,8 @@ decode_buffer (ProfContext *ctx)
                                while (*p) p++;
                                p++;
                        } else if (mtype == TYPE_IMAGE) {
-                               uint64_t flags = decode_uleb128 (p, &p);
-                               if (flags) {
-                                       fprintf (outfile, "non-zero flags in image\n");
-                                       return 0;
-                               }
+                               if (ctx->data_version < 13)
+                                       decode_uleb128 (p, &p); /* flags */
                                if (debug)
                                        fprintf (outfile, "%s image %p (%s) at %llu\n", load_str, (void*)(ptr_base + ptrdiff), p, (unsigned long long) time_base);
                                if (subtype == TYPE_END_LOAD)
@@ -2411,11 +2449,8 @@ decode_buffer (ProfContext *ctx)
                                while (*p) p++;
                                p++;
                        } else if (mtype == TYPE_ASSEMBLY) {
-                               uint64_t flags = decode_uleb128 (p, &p);
-                               if (flags) {
-                                       fprintf (outfile, "non-zero flags in assembly\n");
-                                       return 0;
-                               }
+                               if (ctx->data_version < 13)
+                                       decode_uleb128 (p, &p); /* flags */
                                if (debug)
                                        fprintf (outfile, "%s assembly %p (%s) at %llu\n", load_str, (void*)(ptr_base + ptrdiff), p, (unsigned long long) time_base);
                                if (subtype == TYPE_END_LOAD)
@@ -2423,11 +2458,8 @@ decode_buffer (ProfContext *ctx)
                                while (*p) p++;
                                p++;
                        } else if (mtype == TYPE_DOMAIN) {
-                               uint64_t flags = decode_uleb128 (p, &p);
-                               if (flags) {
-                                       fprintf (outfile, "non-zero flags in domain\n");
-                                       return 0;
-                               }
+                               if (ctx->data_version < 13)
+                                       decode_uleb128 (p, &p); /* flags */
                                DomainContext *nd = get_domain (ctx, ptr_base + ptrdiff);
                                /* no subtype means it's a name event, rather than start/stop */
                                if (subtype == 0)
@@ -2443,22 +2475,16 @@ decode_buffer (ProfContext *ctx)
                                        p++;
                                }
                        } else if (mtype == TYPE_CONTEXT) {
-                               uint64_t flags = decode_uleb128 (p, &p);
-                               if (flags) {
-                                       fprintf (outfile, "non-zero flags in context\n");
-                                       return 0;
-                               }
+                               if (ctx->data_version < 13)
+                                       decode_uleb128 (p, &p); /* flags */
                                intptr_t domaindiff = decode_sleb128 (p, &p);
                                if (debug)
                                        fprintf (outfile, "%s context %p (%p) at %llu\n", load_str, (void*)(ptr_base + ptrdiff), (void *) (ptr_base + domaindiff), (unsigned long long) time_base);
                                if (subtype == TYPE_END_LOAD)
                                        get_remctx (ctx, ptr_base + ptrdiff)->domain_id = ptr_base + domaindiff;
                        } else if (mtype == TYPE_THREAD) {
-                               uint64_t flags = decode_uleb128 (p, &p);
-                               if (flags) {
-                                       fprintf (outfile, "non-zero flags in thread\n");
-                                       return 0;
-                               }
+                               if (ctx->data_version < 13)
+                                       decode_uleb128 (p, &p); /* flags */
                                ThreadContext *nt = get_thread (ctx, ptr_base + ptrdiff);
                                /* no subtype means it's a name event, rather than start/stop */
                                if (subtype == 0)
@@ -2493,7 +2519,7 @@ decode_buffer (ProfContext *ctx)
                                fprintf (outfile, "alloced object %p, size %llu (%s) at %llu\n", (void*)OBJ_ADDR (objdiff), (unsigned long long) len, lookup_class (ptr_base + ptrdiff)->name, (unsigned long long) time_base);
                        if (has_bt) {
                                num_bt = 8;
-                               frames = decode_bt (sframes, &num_bt, p, &p, ptr_base);
+                               frames = decode_bt (ctx, sframes, &num_bt, p, &p, ptr_base, &method_base);
                                if (!frames) {
                                        fprintf (outfile, "Cannot load backtrace\n");
                                        return 0;
@@ -2561,7 +2587,14 @@ decode_buffer (ProfContext *ctx)
                        if (subtype == TYPE_HEAP_OBJECT) {
                                HeapObjectDesc *ho = NULL;
                                int i;
-                               intptr_t objdiff = decode_sleb128 (p + 1, &p);
+                               intptr_t objdiff;
+                               if (ctx->data_version > 12) {
+                                       uint64_t tdiff = decode_uleb128 (p + 1, &p);
+                                       LOG_TIME (time_base, tdiff);
+                                       time_base += tdiff;
+                                       objdiff = decode_sleb128 (p, &p);
+                               } else
+                                       objdiff = decode_sleb128 (p + 1, &p);
                                intptr_t ptrdiff = decode_sleb128 (p, &p);
                                uint64_t size = decode_uleb128 (p, &p);
                                uintptr_t num = decode_uleb128 (p, &p);
@@ -2594,12 +2627,23 @@ decode_buffer (ProfContext *ctx)
                                if (debug && size)
                                        fprintf (outfile, "traced object %p, size %llu (%s), refs: %zd\n", (void*)OBJ_ADDR (objdiff), (unsigned long long) size, cd->name, num);
                        } else if (subtype == TYPE_HEAP_ROOT) {
-                               uintptr_t num = decode_uleb128 (p + 1, &p);
+                               uintptr_t num;
+                               if (ctx->data_version > 12) {
+                                       uint64_t tdiff = decode_uleb128 (p + 1, &p);
+                                       LOG_TIME (time_base, tdiff);
+                                       time_base += tdiff;
+                                       num = decode_uleb128 (p, &p);
+                               } else
+                                       num = decode_uleb128 (p + 1, &p);
                                uintptr_t gc_num G_GNUC_UNUSED = decode_uleb128 (p, &p);
                                int i;
                                for (i = 0; i < num; ++i) {
                                        intptr_t objdiff = decode_sleb128 (p, &p);
-                                       int root_type = decode_uleb128 (p, &p);
+                                       int root_type;
+                                       if (ctx->data_version > 12)
+                                               root_type = *p++;
+                                       else
+                                               root_type = decode_uleb128 (p, &p);
                                        /* we just discard the extra info for now */
                                        uintptr_t extra_info = decode_uleb128 (p, &p);
                                        if (debug)
@@ -2670,7 +2714,7 @@ decode_buffer (ProfContext *ctx)
                                }
                                if (has_bt) {
                                        num_bt = 8;
-                                       frames = decode_bt (sframes, &num_bt, p, &p, ptr_base);
+                                       frames = decode_bt (ctx, sframes, &num_bt, p, &p, ptr_base, &method_base);
                                        if (!frames) {
                                                fprintf (outfile, "Cannot load backtrace\n");
                                                return 0;
@@ -2714,7 +2758,7 @@ decode_buffer (ProfContext *ctx)
                }
                case TYPE_EXCEPTION: {
                        int subtype = *p & 0x70;
-                       int has_bt = *p & TYPE_EXCEPTION_BT;
+                       int has_bt = *p & TYPE_THROW_BT;
                        uint64_t tdiff = decode_uleb128 (p + 1, &p);
                        MethodDesc* sframes [8];
                        MethodDesc** frames = sframes;
@@ -2725,7 +2769,11 @@ decode_buffer (ProfContext *ctx)
                        if (!(time_base >= time_from && time_base < time_to))
                                record = 0;
                        if (subtype == TYPE_CLAUSE) {
-                               int clause_type = decode_uleb128 (p, &p);
+                               int clause_type;
+                               if (ctx->data_version > 12)
+                                       clause_type = *p++;
+                               else
+                                       clause_type = decode_uleb128 (p, &p);
                                int clause_num = decode_uleb128 (p, &p);
                                int64_t ptrdiff = decode_sleb128 (p, &p);
                                method_base += ptrdiff;
@@ -2739,7 +2787,7 @@ decode_buffer (ProfContext *ctx)
                                        throw_count++;
                                if (has_bt) {
                                        has_bt = 8;
-                                       frames = decode_bt (sframes, &has_bt, p, &p, ptr_base);
+                                       frames = decode_bt (ctx, sframes, &has_bt, p, &p, ptr_base, &method_base);
                                        if (!frames) {
                                                fprintf (outfile, "Cannot load backtrace\n");
                                                return 0;
@@ -2763,7 +2811,11 @@ decode_buffer (ProfContext *ctx)
                        LOG_TIME (time_base, tdiff);
                        time_base += tdiff;
                        if (subtype == TYPE_JITHELPER) {
-                               int type = decode_uleb128 (p, &p);
+                               int type;
+                               if (ctx->data_version > 12)
+                                       type = *p++;
+                               else
+                                       type = decode_uleb128 (p, &p);
                                intptr_t codediff = decode_sleb128 (p, &p);
                                int codelen = decode_uleb128 (p, &p);
                                const char *name;
@@ -2785,8 +2837,18 @@ decode_buffer (ProfContext *ctx)
                        int subtype = *p & 0xf0;
                        if (subtype == TYPE_SAMPLE_HIT) {
                                int i;
-                               int sample_type = decode_uleb128 (p + 1, &p);
-                               uint64_t tstamp = decode_uleb128 (p, &p);
+                               int sample_type;
+                               uint64_t tstamp;
+                               if (ctx->data_version > 12) {
+                                       uint64_t tdiff = decode_uleb128 (p + 1, &p);
+                                       LOG_TIME (time_base, tdiff);
+                                       time_base += tdiff;
+                                       sample_type = *p++;
+                                       tstamp = time_base;
+                               } else {
+                                       sample_type = decode_uleb128 (p + 1, &p);
+                                       tstamp = decode_uleb128 (p, &p);
+                               }
                                void *tid = (void *) thread_id;
                                if (ctx->data_version > 10)
                                        tid = (void *) (ptr_base + decode_sleb128 (p, &p));
@@ -2803,17 +2865,26 @@ decode_buffer (ProfContext *ctx)
                                        for (i = 0; i < count; ++i) {
                                                MethodDesc *method;
                                                int64_t ptrdiff = decode_sleb128 (p, &p);
-                                               int il_offset = decode_sleb128 (p, &p);
-                                               int native_offset = decode_sleb128 (p, &p);
                                                method_base += ptrdiff;
                                                method = lookup_method (method_base);
                                                if (debug)
-                                                       fprintf (outfile, "sample hit bt %d: %s at IL offset %d (native: %d)\n", i, method->name, il_offset, native_offset);
+                                                       fprintf (outfile, "sample hit bt %d: %s\n", i, method->name);
+                                               if (ctx->data_version < 13) {
+                                                       decode_sleb128 (p, &p); /* il offset */
+                                                       decode_sleb128 (p, &p); /* native offset */
+                                               }
                                        }
                                }
                        } else if (subtype == TYPE_SAMPLE_USYM) {
                                /* un unmanaged symbol description */
-                               uintptr_t addr = ptr_base + decode_sleb128 (p + 1, &p);
+                               uintptr_t addr;
+                               if (ctx->data_version > 12) {
+                                       uint64_t tdiff = decode_uleb128 (p + 1, &p);
+                                       LOG_TIME (time_base, tdiff);
+                                       time_base += tdiff;
+                                       addr = ptr_base + decode_sleb128 (p, &p);
+                               } else
+                                       addr = ptr_base + decode_sleb128 (p + 1, &p);
                                uintptr_t size = decode_uleb128 (p, &p);
                                char *name;
                                name = pstrdup ((char*)p);
@@ -2838,7 +2909,14 @@ decode_buffer (ProfContext *ctx)
                                while (*p) p++;
                                p++;
                        } else if (subtype == TYPE_SAMPLE_COUNTERS_DESC) {
-                               uint64_t i, len = decode_uleb128 (p + 1, &p);
+                               uint64_t i, len;
+                               if (ctx->data_version > 12) {
+                                       uint64_t tdiff = decode_uleb128 (p + 1, &p);
+                                       LOG_TIME (time_base, tdiff);
+                                       time_base += tdiff;
+                                       len = decode_uleb128 (p, &p);
+                               } else
+                                       len = decode_uleb128 (p + 1, &p);
                                for (i = 0; i < len; i++) {
                                        uint64_t type, unit, variance, index;
                                        uint64_t section = decode_uleb128 (p, &p);
@@ -2851,9 +2929,15 @@ decode_buffer (ProfContext *ctx)
                                        }
                                        name = pstrdup ((char*)p);
                                        while (*p++);
-                                       type = decode_uleb128 (p, &p);
-                                       unit = decode_uleb128 (p, &p);
-                                       variance = decode_uleb128 (p, &p);
+                                       if (ctx->data_version > 12) {
+                                               type = *p++;
+                                               unit = *p++;
+                                               variance = *p++;
+                                       } else {
+                                               type = decode_uleb128 (p, &p);
+                                               unit = decode_uleb128 (p, &p);
+                                               variance = decode_uleb128 (p, &p);
+                                       }
                                        index = decode_uleb128 (p, &p);
                                        add_counter (section_str, name, (int)type, (int)unit, (int)variance, (int)index);
                                }
@@ -2861,7 +2945,14 @@ decode_buffer (ProfContext *ctx)
                                int i;
                                CounterValue *value, *previous = NULL;
                                CounterList *list;
-                               uint64_t timestamp = decode_uleb128 (p + 1, &p);
+                               uint64_t timestamp; // milliseconds since startup
+                               if (ctx->data_version > 12) {
+                                       uint64_t tdiff = decode_uleb128 (p + 1, &p);
+                                       LOG_TIME (time_base, tdiff);
+                                       time_base += tdiff;
+                                       timestamp = (time_base - startup_time) / 1000 / 1000;
+                               } else
+                                       timestamp = decode_uleb128 (p + 1, &p);
                                uint64_t time_between = timestamp / 1000 * 1000 * 1000 * 1000 + startup_time;
                                while (1) {
                                        uint64_t type, index = decode_uleb128 (p, &p);
@@ -2875,7 +2966,10 @@ decode_buffer (ProfContext *ctx)
                                                }
                                        }
 
-                                       type = decode_uleb128 (p, &p);
+                                       if (ctx->data_version > 12)
+                                               type = *p++;
+                                       else
+                                               type = decode_uleb128 (p, &p);
 
                                        value = (CounterValue *)calloc (1, sizeof (CounterValue));
                                        value->timestamp = timestamp;
@@ -2939,6 +3033,13 @@ decode_buffer (ProfContext *ctx)
                                int token, n_offsets, method_id;
 
                                p++;
+
+                               if (ctx->data_version > 12) {
+                                       uint64_t tdiff = decode_uleb128 (p, &p);
+                                       LOG_TIME (time_base, tdiff);
+                                       time_base += tdiff;
+                               }
+
                                assembly = (const char *)p; while (*p) p++; p++;
                                klass = (const char *)p; while (*p) p++; p++;
                                name = (const char *)p; while (*p) p++; p++;
@@ -2968,6 +3069,13 @@ decode_buffer (ProfContext *ctx)
                                int offset, count, line, column, method_id;
 
                                p++;
+
+                               if (ctx->data_version > 12) {
+                                       uint64_t tdiff = decode_uleb128 (p, &p);
+                                       LOG_TIME (time_base, tdiff);
+                                       time_base += tdiff;
+                               }
+
                                method_id = decode_uleb128 (p, &p);
                                offset = decode_uleb128 (p, &p);
                                count = decode_uleb128 (p, &p);
@@ -2989,6 +3097,12 @@ decode_buffer (ProfContext *ctx)
                                int number_of_methods, fully_covered, partially_covered;
                                p++;
 
+                               if (ctx->data_version > 12) {
+                                       uint64_t tdiff = decode_uleb128 (p, &p);
+                                       LOG_TIME (time_base, tdiff);
+                                       time_base += tdiff;
+                               }
+
                                name = (char *)p; while (*p) p++; p++;
                                guid = (char *)p; while (*p) p++; p++;
                                filename = (char *)p; while (*p) p++; p++;
@@ -3012,6 +3126,12 @@ decode_buffer (ProfContext *ctx)
                                int number_of_methods, fully_covered, partially_covered;
                                p++;
 
+                               if (ctx->data_version > 12) {
+                                       uint64_t tdiff = decode_uleb128 (p, &p);
+                                       LOG_TIME (time_base, tdiff);
+                                       time_base += tdiff;
+                               }
+
                                assembly_name = (char *)p; while (*p) p++; p++;
                                class_name = (char *)p; while (*p) p++; p++;
                                number_of_methods = decode_uleb128 (p, &p);
@@ -3033,6 +3153,18 @@ decode_buffer (ProfContext *ctx)
                        }
                        break;
                }
+               case TYPE_META: {
+                       int subtype = *p & 0xf0;
+                       uint64_t tdiff = decode_uleb128 (p + 1, &p);
+                       LOG_TIME (time_base, tdiff);
+                       time_base += tdiff;
+                       if (subtype == TYPE_SYNC_POINT) {
+                               int type = *p++;
+                               if (debug)
+                                       fprintf (outfile, "sync point %i (%s)\n", type, sync_point_name (type));
+                       }
+                       break;
+               }
                default:
                        fprintf (outfile, "unhandled profiler event: 0x%x at file offset: %llu + %lld (len: %d\n)\n", *p, (unsigned long long) file_offset, (long long) (p - ctx->buf), len);
                        exit (1);
@@ -3045,6 +3177,20 @@ decode_buffer (ProfContext *ctx)
        return 1;
 }
 
+static int
+read_header_string (ProfContext *ctx, char **field)
+{
+       if (!load_data (ctx, 4))
+               return 0;
+
+       if (!load_data (ctx, read_int32 (ctx->buf)))
+               return 0;
+
+       *field = pstrdup ((const char *) ctx->buf);
+
+       return 1;
+}
+
 static ProfContext*
 load_file (char *name)
 {
@@ -3062,7 +3208,7 @@ load_file (char *name)
        if (ctx->file != stdin)
                ctx->gzfile = gzdopen (fileno (ctx->file), "rb");
 #endif
-       if (!load_data (ctx, 32))
+       if (!load_data (ctx, 30))
                return NULL;
        p = ctx->buf;
        if (read_int32 (p) != LOG_HEADER_ID || p [6] > LOG_DATA_VERSION)
@@ -3079,6 +3225,17 @@ load_file (char *name)
        ctx->timer_overhead = read_int32 (p + 16);
        ctx->pid = read_int32 (p + 24);
        ctx->port = read_int16 (p + 28);
+       if (ctx->version_major >= 1) {
+               if (!read_header_string (ctx, &ctx->args))
+                       return NULL;
+               if (!read_header_string (ctx, &ctx->arch))
+                       return NULL;
+               if (!read_header_string (ctx, &ctx->os))
+                       return NULL;
+       } else {
+               if (!load_data (ctx, 2)) /* old opsys field, was never used */
+                       return NULL;
+       }
        return ctx;
 }
 
@@ -3116,6 +3273,11 @@ dump_header (ProfContext *ctx)
        fprintf (outfile, "\nMono log profiler data\n");
        fprintf (outfile, "\tProfiler version: %d.%d\n", ctx->version_major, ctx->version_minor);
        fprintf (outfile, "\tData version: %d\n", ctx->data_version);
+       if (ctx->version_major >= 1) {
+               fprintf (outfile, "\tArguments: %s\n", ctx->args);
+               fprintf (outfile, "\tArchitecture: %s\n", ctx->arch);
+               fprintf (outfile, "\tOperating system: %s\n", ctx->os);
+       }
        fprintf (outfile, "\tMean timer overhead: %d nanoseconds\n", ctx->timer_overhead);
        fprintf (outfile, "\tProgram startup: %s", t);
        if (ctx->pid)
@@ -3768,9 +3930,9 @@ dump_stats (void)
        DUMP_EVENT_STAT (TYPE_METHOD, TYPE_EXC_LEAVE);
        DUMP_EVENT_STAT (TYPE_METHOD, TYPE_JIT);
 
-       DUMP_EVENT_STAT (TYPE_EXCEPTION, TYPE_THROW);
+       DUMP_EVENT_STAT (TYPE_EXCEPTION, TYPE_THROW_NO_BT);
+       DUMP_EVENT_STAT (TYPE_EXCEPTION, TYPE_THROW_BT);
        DUMP_EVENT_STAT (TYPE_EXCEPTION, TYPE_CLAUSE);
-       DUMP_EVENT_STAT (TYPE_EXCEPTION, TYPE_EXCEPTION_BT);
 
        DUMP_EVENT_STAT (TYPE_MONITOR, TYPE_MONITOR_NO_BT);
        DUMP_EVENT_STAT (TYPE_MONITOR, TYPE_MONITOR_BT);
@@ -3792,6 +3954,8 @@ dump_stats (void)
        DUMP_EVENT_STAT (TYPE_COVERAGE, TYPE_COVERAGE_METHOD);
        DUMP_EVENT_STAT (TYPE_COVERAGE, TYPE_COVERAGE_STATEMENT);
        DUMP_EVENT_STAT (TYPE_COVERAGE, TYPE_COVERAGE_CLASS);
+
+       DUMP_EVENT_STAT (TYPE_META, TYPE_SYNC_POINT);
 }
 
 
index 99e68567571dcf59b3759f143d2642e0861c06de..38fe00625682e73bf5a2d32403c4807e69dddfd5 100644 (file)
@@ -15,8 +15,9 @@
 #include "../metadata/metadata-internals.h"
 #include <mono/metadata/profiler.h>
 #include <mono/metadata/threads.h>
-#include <mono/metadata/mono-gc.h>
 #include <mono/metadata/debug-helpers.h>
+#include <mono/metadata/mono-config.h>
+#include <mono/metadata/mono-gc.h>
 #include <mono/metadata/mono-perfcounters.h>
 #include <mono/metadata/appdomain.h>
 #include <mono/metadata/assembly.h>
 #include <mono/utils/mono-os-mutex.h>
 #include <mono/utils/mono-os-semaphore.h>
 #include <mono/utils/mono-conc-hashtable.h>
+#include <mono/utils/mono-linked-list-set.h>
 #include <mono/utils/lock-free-alloc.h>
 #include <mono/utils/lock-free-queue.h>
 #include <mono/utils/hazard-pointer.h>
 #include <mono/utils/mono-threads.h>
+#include <mono/utils/mono-threads-api.h>
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
@@ -105,8 +108,10 @@ static int read_perf_mmap (MonoProfiler* prof, int cpu);
 
 /* Worst-case size in bytes of a 64-bit value encoded with LEB128. */
 #define LEB128_SIZE 10
-/* Size in bytes of the event ID prefix. */
-#define EVENT_SIZE 1
+/* Size of a value encoded as a single byte. */
+#define BYTE_SIZE 1
+/* Size in bytes of the event prefix (ID + time). */
+#define EVENT_SIZE (BYTE_SIZE + LEB128_SIZE)
 
 static int nocalls = 0;
 static int notraces = 0;
@@ -146,7 +151,7 @@ static gint32 image_unloads;
 static gint32 class_loads;
 static gint32 class_unloads;
 
-typedef struct _LogBuffer LogBuffer;
+static MonoLinkedListSet profiler_thread_list;
 
 /*
  * file format:
@@ -169,7 +174,12 @@ typedef struct _LogBuffer LogBuffer;
  * [flags: 4 bytes] file format flags, should be 0 for now
  * [pid: 4 bytes] pid of the profiled process
  * [port: 2 bytes] tcp port for server if != 0
- * [sysid: 2 bytes] operating system and architecture identifier
+ * [args size: 4 bytes] size of args
+ * [args: string] arguments passed to the profiler
+ * [arch size: 4 bytes] size of arch
+ * [arch: string] architecture the profiler is running on
+ * [os size: 4 bytes] size of os
+ * [os: string] operating system the profiler is running on
  *
  * The multiple byte integers are in little-endian format.
  *
@@ -203,7 +213,9 @@ typedef struct _LogBuffer LogBuffer;
  * [method_base: 8 bytes] base value for MonoMethod pointers
  *
  * event format:
- * [extended info: upper 4 bits] [type: lower 4 bits] [data]*
+ * [extended info: upper 4 bits] [type: lower 4 bits]
+ * [time diff: uleb128] nanoseconds since last timing
+ * [data]*
  * The data that follows depends on type and the extended info.
  * Type is one of the enum values in proflog.h: TYPE_ALLOC, TYPE_GC,
  * TYPE_METADATA, TYPE_METHOD, TYPE_EXCEPTION, TYPE_MONITOR, TYPE_HEAP.
@@ -212,14 +224,13 @@ typedef struct _LogBuffer LogBuffer;
  * strings are represented as a 0-terminated utf8 sequence.
  *
  * backtrace format:
- * [flags: uleb128] must be 0
  * [num: uleb128] number of frames following
- * [frame: sleb128]* num MonoMethod pointers as differences from ptr_base
+ * [frame: sleb128]* mum MonoMethod* as a pointer difference from the last such
+ * pointer or the buffer method_base
  *
  * type alloc format:
  * type: TYPE_ALLOC
  * exinfo: flags: TYPE_ALLOC_BT
- * [time diff: uleb128] nanoseconds since last timing
  * [ptr: sleb128] class as a byte difference from ptr_base
  * [obj: sleb128] object address as a byte difference from obj_base
  * [size: uleb128] size of the object in the heap
@@ -228,13 +239,13 @@ typedef struct _LogBuffer LogBuffer;
  * type GC format:
  * type: TYPE_GC
  * exinfo: one of TYPE_GC_EVENT, TYPE_GC_RESIZE, TYPE_GC_MOVE, TYPE_GC_HANDLE_CREATED[_BT],
- * TYPE_GC_HANDLE_DESTROYED[_BT]
- * [time diff: uleb128] nanoseconds since last timing
+ * TYPE_GC_HANDLE_DESTROYED[_BT], TYPE_GC_FINALIZE_START, TYPE_GC_FINALIZE_END,
+ * TYPE_GC_FINALIZE_OBJECT_START, TYPE_GC_FINALIZE_OBJECT_END
  * if exinfo == TYPE_GC_RESIZE
  *     [heap_size: uleb128] new heap size
  * if exinfo == TYPE_GC_EVENT
- *     [event type: uleb128] GC event (MONO_GC_EVENT_* from profiler.h)
- *     [generation: uleb128] GC generation event refers to
+ *     [event type: byte] GC event (MONO_GC_EVENT_* from profiler.h)
+ *     [generation: byte] GC generation event refers to
  * if exinfo == TYPE_GC_MOVE
  *     [num_objects: uleb128] number of object moves that follow
  *     [objaddr: sleb128]+ num_objects object pointer differences from obj_base
@@ -251,39 +262,32 @@ typedef struct _LogBuffer LogBuffer;
  *     upper bits reserved as flags
  *     [handle: uleb128] GC handle value
  *     If exinfo == TYPE_GC_HANDLE_DESTROYED_BT, a backtrace follows.
+ * if exinfo == TYPE_GC_FINALIZE_OBJECT_{START,END}
+ *     [object: sleb128] the object as a difference from obj_base
  *
  * type metadata format:
  * type: TYPE_METADATA
  * exinfo: one of: TYPE_END_LOAD, TYPE_END_UNLOAD (optional for TYPE_THREAD and TYPE_DOMAIN)
- * [time diff: uleb128] nanoseconds since last timing
  * [mtype: byte] metadata type, one of: TYPE_CLASS, TYPE_IMAGE, TYPE_ASSEMBLY, TYPE_DOMAIN,
  * TYPE_THREAD, TYPE_CONTEXT
  * [pointer: sleb128] pointer of the metadata type depending on mtype
  * if mtype == TYPE_CLASS
  *     [image: sleb128] MonoImage* as a pointer difference from ptr_base
- *     [flags: uleb128] must be 0
  *     [name: string] full class name
  * if mtype == TYPE_IMAGE
- *     [flags: uleb128] must be 0
  *     [name: string] image file name
  * if mtype == TYPE_ASSEMBLY
- *     [flags: uleb128] must be 0
  *     [name: string] assembly name
- * if mtype == TYPE_DOMAIN
- *     [flags: uleb128] must be 0
  * if mtype == TYPE_DOMAIN && exinfo == 0
  *     [name: string] domain friendly name
  * if mtype == TYPE_CONTEXT
- *     [flags: uleb128] must be 0
  *     [domain: sleb128] domain id as pointer
- * if mtype == TYPE_THREAD && (format_version < 11 || (format_version > 10 && exinfo == 0))
- *     [flags: uleb128] must be 0
+ * if mtype == TYPE_THREAD && exinfo == 0
  *     [name: string] thread name
  *
  * type method format:
  * type: TYPE_METHOD
  * exinfo: one of: TYPE_LEAVE, TYPE_ENTER, TYPE_EXC_LEAVE, TYPE_JIT
- * [time diff: uleb128] nanoseconds since last timing
  * [method: sleb128] MonoMethod* as a pointer difference from the last such
  * pointer or the buffer method_base
  * if exinfo == TYPE_JIT
@@ -291,12 +295,23 @@ typedef struct _LogBuffer LogBuffer;
  *     [code size: uleb128] size of the generated code
  *     [name: string] full method name
  *
+ * type exception format:
+ * type: TYPE_EXCEPTION
+ * exinfo: TYPE_THROW_BT flag or one of: TYPE_CLAUSE
+ * if exinfo == TYPE_CLAUSE
+ *     [clause type: byte] MonoExceptionEnum enum value
+ *     [clause index: uleb128] index of the current clause
+ *     [method: sleb128] MonoMethod* as a pointer difference from the last such
+ *     pointer or the buffer method_base
+ * else
+ *     [object: sleb128] the exception object as a difference from obj_base
+ *     if exinfo has TYPE_THROW_BT set, a backtrace follows.
+ *
  * type runtime format:
  * type: TYPE_RUNTIME
  * exinfo: one of: TYPE_JITHELPER
- * [time diff: uleb128] nanoseconds since last timing
  * if exinfo == TYPE_JITHELPER
- *     [type: uleb128] MonoProfilerCodeBufferType enum value
+ *     [type: byte] MonoProfilerCodeBufferType enum value
  *     [buffer address: sleb128] pointer to the native code as a diff from ptr_base
  *     [buffer size: uleb128] size of the generated code
  *     if type == MONO_PROFILER_CODE_BUFFER_SPECIFIC_TRAMPOLINE
@@ -305,7 +320,6 @@ typedef struct _LogBuffer LogBuffer;
  * type monitor format:
  * type: TYPE_MONITOR
  * exinfo: TYPE_MONITOR_BT flag and one of: MONO_PROFILER_MONITOR_(CONTENTION|FAIL|DONE)
- * [time diff: uleb128] nanoseconds since last timing
  * [object: sleb128] the lock object as a difference from obj_base
  * if exinfo.low3bits == MONO_PROFILER_MONITOR_CONTENTION
  *     If the TYPE_MONITOR_BT flag is set, a backtrace follows.
@@ -313,18 +327,14 @@ typedef struct _LogBuffer LogBuffer;
  * type heap format
  * type: TYPE_HEAP
  * exinfo: one of TYPE_HEAP_START, TYPE_HEAP_END, TYPE_HEAP_OBJECT, TYPE_HEAP_ROOT
- * if exinfo == TYPE_HEAP_START
- *     [time diff: uleb128] nanoseconds since last timing
- * if exinfo == TYPE_HEAP_END
- *     [time diff: uleb128] nanoseconds since last timing
  * if exinfo == TYPE_HEAP_OBJECT
  *     [object: sleb128] the object as a difference from obj_base
  *     [class: sleb128] the object MonoClass* as a difference from ptr_base
  *     [size: uleb128] size of the object on the heap
  *     [num_refs: uleb128] number of object references
- *     if (format version > 1) each referenced objref is preceded by a
- *     uleb128 encoded offset: the first offset is from the object address
- *     and each next offset is relative to the previous one
+ *     each referenced objref is preceded by a uleb128 encoded offset: the
+ *     first offset is from the object address and each next offset is relative
+ *     to the previous one
  *     [objrefs: sleb128]+ object referenced as a difference from obj_base
  *     The same object can appear multiple times, but only the first time
  *     with size != 0: in the other cases this data will only be used to
@@ -333,7 +343,7 @@ typedef struct _LogBuffer LogBuffer;
  *     [num_roots: uleb128] number of root references
  *     [num_gc: uleb128] number of major gcs
  *     [object: sleb128] the object as a difference from obj_base
- *     [root_type: uleb128] the root_type: MonoProfileGCRootType (profiler.h)
+ *     [root_type: byte] the root_type: MonoProfileGCRootType (profiler.h)
  *     [extra_info: uleb128] the extra_info value
  *     object, root_type and extra_info are repeated num_roots times
  *
@@ -341,24 +351,18 @@ typedef struct _LogBuffer LogBuffer;
  * type: TYPE_SAMPLE
  * exinfo: one of TYPE_SAMPLE_HIT, TYPE_SAMPLE_USYM, TYPE_SAMPLE_UBIN, TYPE_SAMPLE_COUNTERS_DESC, TYPE_SAMPLE_COUNTERS
  * if exinfo == TYPE_SAMPLE_HIT
- *     [sample_type: uleb128] type of sample (SAMPLE_*)
- *     [timestamp: uleb128] nanoseconds since startup (note: different from other timestamps!)
- *     if (format_version > 10)
- *             [thread: sleb128] thread id as difference from ptr_base
+ *     [sample_type: byte] type of sample (SAMPLE_*)
+ *     [thread: sleb128] thread id as difference from ptr_base
  *     [count: uleb128] number of following instruction addresses
  *     [ip: sleb128]* instruction pointer as difference from ptr_base
- *     if (format_version > 5)
- *             [mbt_count: uleb128] number of managed backtrace info triplets (method + IL offset + native offset)
- *             [method: sleb128]* MonoMethod* as a pointer difference from the last such
- *             pointer or the buffer method_base (the first such method can be also indentified by ip, but this is not neccessarily true)
- *             [il_offset: sleb128]* IL offset inside method where the hit occurred
- *             [native_offset: sleb128]* native offset inside method where the hit occurred
+ *     [mbt_count: uleb128] number of managed backtrace frames
+ *     [method: sleb128]* MonoMethod* as a pointer difference from the last such
+ *     pointer or the buffer method_base (the first such method can be also indentified by ip, but this is not neccessarily true)
  * if exinfo == TYPE_SAMPLE_USYM
  *     [address: sleb128] symbol address as a difference from ptr_base
  *     [size: uleb128] symbol size (may be 0 if unknown)
  *     [name: string] symbol name
  * if exinfo == TYPE_SAMPLE_UBIN
- *     [time diff: uleb128] nanoseconds since last timing
  *     [address: sleb128] address where binary has been loaded
  *     [offset: uleb128] file offset of mapping (the same file can be mapped multiple times)
  *     [size: uleb128] memory size
@@ -370,17 +374,16 @@ typedef struct _LogBuffer LogBuffer;
  *             if section == MONO_COUNTER_PERFCOUNTERS:
  *                     [section_name: string] section name of counter
  *             [name: string] name of counter
- *             [type: uleb128] type of counter
- *             [unit: uleb128] unit of counter
- *             [variance: uleb128] variance of counter
+ *             [type: byte] type of counter
+ *             [unit: byte] unit of counter
+ *             [variance: byte] variance of counter
  *             [index: uleb128] unique index of counter
  * if exinfo == TYPE_SAMPLE_COUNTERS
- *     [timestamp: uleb128] sampling timestamp
  *     while true:
  *             [index: uleb128] unique index of counter
  *             if index == 0:
  *                     break
- *             [type: uleb128] type of counter value
+ *             [type: byte] type of counter value
  *             if type == string:
  *                     if value == null:
  *                             [0: uleb128] 0 -> value is null
@@ -425,23 +428,17 @@ typedef struct _LogBuffer LogBuffer;
  *  [partially_covered: uleb128] the number of partially covered methods
  *    currently partially_covered will always be 0, and fully_covered is the
  *    number of methods that are fully and partially covered.
- */
-
-/*
- * Format oddities that we ought to fix:
- *
- * - Methods written in emit_bt () should be based on the buffer's base
- *   method instead of the base pointer.
- * - The TYPE_SAMPLE_HIT event contains (currently) pointless data like
- *   always-one unmanaged frame count and always-zero IL offsets.
  *
- * These are mostly small things and are not worth a format change by
- * themselves. They should be done when some other major change has to
- * be done to the format.
+ * type meta format:
+ * type: TYPE_META
+ * exinfo: one of: TYPE_SYNC_POINT
+ * if exinfo == TYPE_SYNC_POINT
+ *     [type: byte] MonoProfilerSyncPointType enum value
  */
 
 // Pending data to be written to the log, for a single thread.
 // Threads periodically flush their own LogBuffers by calling safe_send
+typedef struct _LogBuffer LogBuffer;
 struct _LogBuffer {
        // Next (older) LogBuffer in processing queue
        LogBuffer *next;
@@ -453,8 +450,6 @@ struct _LogBuffer {
        uintptr_t last_method;
        uintptr_t obj_base;
        uintptr_t thread_id;
-       int locked;
-       int call_depth;
 
        // Bytes allocated for this LogBuffer
        int size;
@@ -469,16 +464,123 @@ struct _LogBuffer {
        unsigned char buf [1];
 };
 
+typedef struct {
+       MonoLinkedListSetNode node;
+
+       // The current log buffer for this thread.
+       LogBuffer *buffer;
+
+       // Methods referenced by events in `buffer`, see `MethodInfo`.
+       GPtrArray *methods;
+
+       // Current call depth for enter/leave events.
+       int call_depth;
+
+       // Indicates whether this thread is currently writing to its `buffer`.
+       int busy;
+} MonoProfilerThread;
+
 static inline void
 ign_res (int G_GNUC_UNUSED unused, ...)
 {
 }
 
-#define ENTER_LOG(lb,str) if ((lb)->locked) {ign_res (write(2, str, strlen(str))); ign_res (write(2, "\n", 1));return;} else {(lb)->locked++;}
-#define EXIT_LOG(lb) (lb)->locked--;
+/*
+ * These macros create a scope to avoid leaking the buffer returned
+ * from ensure_logbuf () as it may have been invalidated by a GC
+ * thread during STW. If you called init_thread () with add_to_lls =
+ * FALSE, then don't use these macros.
+ */
 
-typedef struct _BinaryObject BinaryObject;
+#define ENTER_LOG \
+       do { \
+               buffer_lock (); \
+               g_assert (!PROF_TLS_GET ()->busy++ && "Why are we trying to write a new event while already writing one?")
+
+#define EXIT_LOG \
+               PROF_TLS_GET ()->busy--; \
+               buffer_unlock (); \
+       } while (0)
+
+static volatile gint32 buffer_rwlock_count;
+static volatile gpointer buffer_rwlock_exclusive;
+
+// Can be used recursively.
+static void
+buffer_lock (void)
+{
+       /*
+        * If the thread holding the exclusive lock tries to modify the
+        * reader count, just make it a no-op. This way, we also avoid
+        * invoking the GC safe point macros below, which could break if
+        * done from a thread that is currently the initiator of STW.
+        *
+        * In other words, we rely on the fact that the GC thread takes
+        * the exclusive lock in the gc_event () callback when the world
+        * is about to stop.
+        */
+       if (InterlockedReadPointer (&buffer_rwlock_exclusive) != (gpointer) thread_id ()) {
+               MONO_ENTER_GC_SAFE;
 
+               while (InterlockedReadPointer (&buffer_rwlock_exclusive))
+                       mono_thread_info_yield ();
+
+               InterlockedIncrement (&buffer_rwlock_count);
+
+               MONO_EXIT_GC_SAFE;
+       }
+
+       mono_memory_barrier ();
+}
+
+static void
+buffer_unlock (void)
+{
+       mono_memory_barrier ();
+
+       // See the comment in buffer_lock ().
+       if (InterlockedReadPointer (&buffer_rwlock_exclusive) == (gpointer) thread_id ())
+               return;
+
+       g_assert (InterlockedRead (&buffer_rwlock_count) && "Why are we trying to decrement a zero reader count?");
+
+       InterlockedDecrement (&buffer_rwlock_count);
+}
+
+// Cannot be used recursively.
+static void
+buffer_lock_excl (void)
+{
+       gpointer tid = (gpointer) thread_id ();
+
+       g_assert (InterlockedReadPointer (&buffer_rwlock_exclusive) != tid && "Why are we taking the exclusive lock twice?");
+
+       MONO_ENTER_GC_SAFE;
+
+       while (InterlockedCompareExchangePointer (&buffer_rwlock_exclusive, tid, 0))
+               mono_thread_info_yield ();
+
+       while (InterlockedRead (&buffer_rwlock_count))
+               mono_thread_info_yield ();
+
+       MONO_EXIT_GC_SAFE;
+
+       mono_memory_barrier ();
+}
+
+static void
+buffer_unlock_excl (void)
+{
+       mono_memory_barrier ();
+
+       g_assert (InterlockedReadPointer (&buffer_rwlock_exclusive) && "Why is the exclusive lock not held?");
+       g_assert (InterlockedReadPointer (&buffer_rwlock_exclusive) == (gpointer) thread_id () && "Why does another thread hold the exclusive lock?");
+       g_assert (!InterlockedRead (&buffer_rwlock_count) && "Why are there readers when the exclusive lock is held?");
+
+       InterlockedWritePointer (&buffer_rwlock_exclusive, NULL);
+}
+
+typedef struct _BinaryObject BinaryObject;
 struct _BinaryObject {
        BinaryObject *next;
        void *addr;
@@ -490,6 +592,7 @@ struct _MonoProfiler {
 #if defined (HAVE_SYS_ZLIB)
        gzFile gzfile;
 #endif
+       char *args;
        uint64_t startup_time;
        int pipe_output;
        int last_gc_gen_started;
@@ -502,6 +605,8 @@ struct _MonoProfiler {
        pthread_t dumper_thread;
 #endif
        volatile gint32 run_writer_thread;
+       MonoLockFreeAllocSizeClass writer_entry_size_class;
+       MonoLockFreeAllocator writer_entry_allocator;
        MonoLockFreeQueue writer_queue;
        MonoSemType writer_queue_sem;
        MonoConcurrentHashTable *method_table;
@@ -516,45 +621,48 @@ struct _MonoProfiler {
        GPtrArray *coverage_filters;
 };
 
-typedef struct _WriterQueueEntry WriterQueueEntry;
-struct _WriterQueueEntry {
+typedef struct {
        MonoLockFreeQueueNode node;
        GPtrArray *methods;
        LogBuffer *buffer;
-};
+} WriterQueueEntry;
 
-typedef struct _MethodInfo MethodInfo;
-struct _MethodInfo {
+#define WRITER_ENTRY_BLOCK_SIZE (mono_pagesize ())
+
+typedef struct {
        MonoMethod *method;
        MonoJitInfo *ji;
        uint64_t time;
-};
-
-#ifdef TLS_INIT
-#undef TLS_INIT
-#endif
+} MethodInfo;
 
 #ifdef HOST_WIN32
-#define TLS_SET(x,y) (TlsSetValue (x, y))
-#define TLS_GET(t,x) ((t *) TlsGetValue (x))
-#define TLS_INIT(x) (x = TlsAlloc ())
-static int tlsbuffer;
-static int tlsmethodlist;
+
+#define PROF_TLS_SET(VAL) (TlsSetValue (profiler_tls, (VAL)))
+#define PROF_TLS_GET() ((MonoProfilerThread *) TlsGetValue (profiler_tls))
+#define PROF_TLS_INIT() (profiler_tls = TlsAlloc ())
+#define PROF_TLS_FREE() (TlsFree (profiler_tls))
+
+static DWORD profiler_tls;
+
 #elif HAVE_KW_THREAD
-#define TLS_SET(x,y) (x = y)
-#define TLS_GET(t,x) (x)
-#define TLS_INIT(x)
-static __thread LogBuffer* tlsbuffer = NULL;
-static __thread GPtrArray* tlsmethodlist = NULL;
+
+#define PROF_TLS_SET(VAL) (profiler_tls = (VAL))
+#define PROF_TLS_GET() (profiler_tls)
+#define PROF_TLS_INIT()
+#define PROF_TLS_FREE()
+
+static __thread MonoProfilerThread *profiler_tls;
+
 #else
-#define TLS_SET(x,y) (pthread_setspecific (x, y))
-#define TLS_GET(t,x) ((t *) pthread_getspecific (x))
-#define TLS_INIT(x) (pthread_key_create (&x, NULL))
-static pthread_key_t tlsbuffer;
-static pthread_key_t tlsmethodlist;
-#endif
 
-static void safe_send (MonoProfiler *profiler, LogBuffer *logbuffer);
+#define PROF_TLS_SET(VAL) (pthread_setspecific (profiler_tls, (VAL)))
+#define PROF_TLS_GET() ((MonoProfilerThread *) pthread_getspecific (profiler_tls))
+#define PROF_TLS_INIT() (pthread_key_create (&profiler_tls, NULL))
+#define PROF_TLS_FREE() (pthread_key_delete (&profiler_tls))
+
+static pthread_key_t profiler_tls;
+
+#endif
 
 static char*
 pstrdup (const char *s)
@@ -581,19 +689,67 @@ create_buffer (void)
 }
 
 static void
-init_thread (void)
+init_buffer_state (MonoProfilerThread *thread)
 {
-       if (!TLS_GET (LogBuffer, tlsbuffer)) {
-               LogBuffer *logbuffer = create_buffer ();
-               TLS_SET (tlsbuffer, logbuffer);
-               logbuffer->thread_id = thread_id ();
-       }
-       if (!TLS_GET (GPtrArray, tlsmethodlist)) {
-               GPtrArray *methodlist = g_ptr_array_new ();
-               TLS_SET (tlsmethodlist, methodlist);
+       thread->buffer = create_buffer ();
+       thread->methods = NULL;
+}
+
+static void
+clear_hazard_pointers (MonoThreadHazardPointers *hp)
+{
+       mono_hazard_pointer_clear (hp, 0);
+       mono_hazard_pointer_clear (hp, 1);
+       mono_hazard_pointer_clear (hp, 2);
+}
+
+static MonoProfilerThread *
+init_thread (gboolean add_to_lls)
+{
+       MonoProfilerThread *thread = PROF_TLS_GET ();
+
+       /*
+        * Sometimes we may try to initialize a thread twice. One example is the
+        * main thread: We initialize it when setting up the profiler, but we will
+        * also get a thread_start () callback for it. Another example is when
+        * attaching new threads to the runtime: We may get a gc_alloc () callback
+        * for that thread's thread object (where we initialize it), soon followed
+        * by a thread_start () callback.
+        *
+        * These cases are harmless anyhow. Just return if we've already done the
+        * initialization work.
+        */
+       if (thread)
+               return thread;
+
+       thread = malloc (sizeof (MonoProfilerThread));
+       thread->node.key = thread_id ();
+       thread->call_depth = 0;
+       thread->busy = 0;
+
+       init_buffer_state (thread);
+
+       /*
+        * Some internal profiler threads don't need to be cleaned up
+        * by the main thread on shutdown.
+        */
+       if (add_to_lls) {
+               MonoThreadHazardPointers *hp = mono_hazard_pointer_get ();
+               g_assert (mono_lls_insert (&profiler_thread_list, hp, &thread->node) && "Why can't we insert the thread in the LLS?");
+               clear_hazard_pointers (hp);
        }
 
-       //printf ("thread %p at time %llu\n", (void*)logbuffer->thread_id, logbuffer->time_base);
+       PROF_TLS_SET (thread);
+
+       return thread;
+}
+
+// Only valid if init_thread () was called with add_to_lls = FALSE.
+static void
+deinit_thread (MonoProfilerThread *thread)
+{
+       free (thread);
+       PROF_TLS_SET (NULL);
 }
 
 static LogBuffer *
@@ -602,31 +758,48 @@ ensure_logbuf_inner (LogBuffer *old, int bytes)
        if (old && old->cursor + bytes + 100 < old->buf_end)
                return old;
 
-       LogBuffer *new_ = (LogBuffer *)create_buffer ();
-       new_->thread_id = thread_id ();
+       LogBuffer *new_ = create_buffer ();
        new_->next = old;
 
-       if (old)
-               new_->call_depth = old->call_depth;
-
        return new_;
 }
 
-static LogBuffer*
-ensure_logbuf (int bytes)
+// Only valid if init_thread () was called with add_to_lls = FALSE.
+static LogBuffer *
+ensure_logbuf_unsafe (int bytes)
 {
-       LogBuffer *old = TLS_GET (LogBuffer, tlsbuffer);
+       MonoProfilerThread *thread = PROF_TLS_GET ();
+       LogBuffer *old = thread->buffer;
        LogBuffer *new_ = ensure_logbuf_inner (old, bytes);
 
        if (new_ == old)
                return old; // Still enough space.
 
-       TLS_SET (tlsbuffer, new_);
-       init_thread ();
+       thread->buffer = new_;
 
        return new_;
 }
 
+/*
+ * Any calls to this function should be wrapped in the ENTER_LOG and
+ * EXIT_LOG macros to prevent the returned pointer from leaking
+ * outside of the critical region created by the calls to buffer_lock ()
+ * and buffer_unlock () that those macros insert. If the pointer leaks,
+ * it can and will lead to crashes as the GC or helper thread may
+ * invalidate the pointer at any time.
+ *
+ * Note: If you're calling from a thread that called init_thread () with
+ * add_to_lls = FALSE, you should use ensure_logbuf_unsafe () and omit
+ * the macros.
+ */
+static LogBuffer*
+ensure_logbuf (int bytes)
+{
+       g_assert (PROF_TLS_GET ()->busy && "Why are we trying to expand our buffer without the busy flag set?");
+
+       return ensure_logbuf_unsafe (bytes);
+}
+
 static void
 emit_byte (LogBuffer *logbuffer, int value)
 {
@@ -657,6 +830,19 @@ emit_time (LogBuffer *logbuffer, uint64_t value)
        assert (logbuffer->cursor <= logbuffer->buf_end);
 }
 
+static void
+emit_event_time (LogBuffer *logbuffer, int event, uint64_t time)
+{
+       emit_byte (logbuffer, event);
+       emit_time (logbuffer, time);
+}
+
+static void
+emit_event (LogBuffer *logbuffer, int event)
+{
+       emit_event_time (logbuffer, event, current_time ());
+}
+
 static void
 emit_svalue (LogBuffer *logbuffer, int64_t value)
 {
@@ -751,13 +937,15 @@ register_method_local (MonoProfiler *prof, MonoMethod *method, MonoJitInfo *ji)
                 */
                //g_assert (ji);
 
-               MethodInfo *info = (MethodInfo *)malloc (sizeof (MethodInfo));
+               MethodInfo *info = (MethodInfo *) malloc (sizeof (MethodInfo));
 
                info->method = method;
                info->ji = ji;
                info->time = current_time ();
 
-               g_ptr_array_add (TLS_GET (GPtrArray, tlsmethodlist), info);
+               MonoProfilerThread *thread = PROF_TLS_GET ();
+               GPtrArray *arr = thread->methods ? thread->methods : (thread->methods = g_ptr_array_new ());
+               g_ptr_array_add (arr, info);
        }
 }
 
@@ -768,13 +956,6 @@ emit_method (MonoProfiler *prof, LogBuffer *logbuffer, MonoMethod *method)
        emit_method_inner (logbuffer, method);
 }
 
-static void
-emit_method_as_ptr (MonoProfiler *prof, LogBuffer *logbuffer, MonoMethod *method)
-{
-       register_method_local (prof, method, NULL);
-       emit_ptr (logbuffer, method);
-}
-
 static void
 emit_obj (LogBuffer *logbuffer, void *ptr)
 {
@@ -845,52 +1026,132 @@ write_int64 (char *buf, int64_t value)
        return buf + 8;
 }
 
+static char *
+write_header_string (char *p, const char *str)
+{
+       size_t len = strlen (str) + 1;
+
+       p = write_int32 (p, len);
+       strcpy (p, str);
+
+       return p + len;
+}
+
 static void
 dump_header (MonoProfiler *profiler)
 {
-       char hbuf [128];
+       const char *args = profiler->args;
+       const char *arch = mono_config_get_cpu ();
+       const char *os = mono_config_get_os ();
+
+       char *hbuf = malloc (
+               sizeof (gint32) /* header id */ +
+               sizeof (gint8) /* major version */ +
+               sizeof (gint8) /* minor version */ +
+               sizeof (gint8) /* data version */ +
+               sizeof (gint8) /* word size */ +
+               sizeof (gint64) /* startup time */ +
+               sizeof (gint32) /* timer overhead */ +
+               sizeof (gint32) /* flags */ +
+               sizeof (gint32) /* process id */ +
+               sizeof (gint16) /* command port */ +
+               sizeof (gint32) + strlen (args) + 1 /* arguments */ +
+               sizeof (gint32) + strlen (arch) + 1 /* architecture */ +
+               sizeof (gint32) + strlen (os) + 1 /* operating system */
+       );
        char *p = hbuf;
+
        p = write_int32 (p, LOG_HEADER_ID);
        *p++ = LOG_VERSION_MAJOR;
        *p++ = LOG_VERSION_MINOR;
        *p++ = LOG_DATA_VERSION;
-       *p++ = sizeof (void*);
-       p = write_int64 (p, ((uint64_t)time (NULL)) * 1000); /* startup time */
-       p = write_int32 (p, get_timer_overhead ()); /* timer overhead */
+       *p++ = sizeof (void *);
+       p = write_int64 (p, ((uint64_t) time (NULL)) * 1000);
+       p = write_int32 (p, get_timer_overhead ());
        p = write_int32 (p, 0); /* flags */
-       p = write_int32 (p, process_id ()); /* pid */
-       p = write_int16 (p, profiler->command_port); /* port */
-       p = write_int16 (p, 0); /* opsystem */
+       p = write_int32 (p, process_id ());
+       p = write_int16 (p, profiler->command_port);
+       p = write_header_string (p, args);
+       p = write_header_string (p, arch);
+       p = write_header_string (p, os);
+
 #if defined (HAVE_SYS_ZLIB)
        if (profiler->gzfile) {
                gzwrite (profiler->gzfile, hbuf, p - hbuf);
-       } else {
+       } else
+#endif
+       {
                fwrite (hbuf, p - hbuf, 1, profiler->file);
+               fflush (profiler->file);
        }
-#else
-       fwrite (hbuf, p - hbuf, 1, profiler->file);
-       fflush (profiler->file);
-#endif
+
+       free (hbuf);
 }
 
 static void
-send_buffer (MonoProfiler *prof, GPtrArray *methods, LogBuffer *buffer)
+send_buffer (MonoProfiler *prof, MonoProfilerThread *thread)
 {
-       WriterQueueEntry *entry = (WriterQueueEntry *)calloc (1, sizeof (WriterQueueEntry));
+       WriterQueueEntry *entry = mono_lock_free_alloc (&prof->writer_entry_allocator);
+       entry->methods = thread->methods;
+       entry->buffer = thread->buffer;
+
        mono_lock_free_queue_node_init (&entry->node, FALSE);
-       entry->methods = methods;
-       entry->buffer = buffer;
+
        mono_lock_free_queue_enqueue (&prof->writer_queue, &entry->node);
        mono_os_sem_post (&prof->writer_queue_sem);
 }
 
+static void
+remove_thread (MonoProfiler *prof, MonoProfilerThread *thread, gboolean from_callback)
+{
+       MonoThreadHazardPointers *hp = mono_hazard_pointer_get ();
+
+       if (mono_lls_remove (&profiler_thread_list, hp, &thread->node)) {
+               LogBuffer *buffer = thread->buffer;
+
+               /*
+                * No need to take the buffer lock here as no other threads can
+                * be accessing this buffer anymore.
+                */
+
+               if (!from_callback) {
+                       /*
+                        * The thread is being cleaned up by the main thread during
+                        * shutdown. This typically happens for internal runtime
+                        * threads. We need to synthesize a thread end event.
+                        */
+
+                       buffer = ensure_logbuf_inner (buffer,
+                               EVENT_SIZE /* event */ +
+                               BYTE_SIZE /* type */ +
+                               LEB128_SIZE /* tid */
+                       );
+
+                       emit_event (buffer, TYPE_END_UNLOAD | TYPE_METADATA);
+                       emit_byte (buffer, TYPE_THREAD);
+                       emit_ptr (buffer, (void *) thread->node.key);
+               }
+
+               send_buffer (prof, thread);
+
+               mono_thread_hazardous_try_free (thread, free);
+       }
+
+       clear_hazard_pointers (hp);
+
+       if (from_callback)
+               PROF_TLS_SET (NULL);
+}
+
 static void
 dump_buffer (MonoProfiler *profiler, LogBuffer *buf)
 {
        char hbuf [128];
        char *p = hbuf;
+
        if (buf->next)
                dump_buffer (profiler, buf->next);
+
        p = write_int32 (p, BUF_ID);
        p = write_int32 (p, buf->cursor - buf->buf);
        p = write_int64 (p, buf->time_base);
@@ -898,21 +1159,31 @@ dump_buffer (MonoProfiler *profiler, LogBuffer *buf)
        p = write_int64 (p, buf->obj_base);
        p = write_int64 (p, buf->thread_id);
        p = write_int64 (p, buf->method_base);
+
 #if defined (HAVE_SYS_ZLIB)
        if (profiler->gzfile) {
                gzwrite (profiler->gzfile, hbuf, p - hbuf);
                gzwrite (profiler->gzfile, buf->buf, buf->cursor - buf->buf);
-       } else {
+       } else
 #endif
+       {
                fwrite (hbuf, p - hbuf, 1, profiler->file);
                fwrite (buf->buf, buf->cursor - buf->buf, 1, profiler->file);
                fflush (profiler->file);
-#if defined (HAVE_SYS_ZLIB)
        }
-#endif
+
        free_buffer (buf, buf->size);
 }
 
+static void
+dump_buffer_threadless (MonoProfiler *profiler, LogBuffer *buf)
+{
+       for (LogBuffer *iter = buf; iter; iter = iter->next)
+               iter->thread_id = 0;
+
+       dump_buffer (profiler, buf);
+}
+
 static void
 process_requests (MonoProfiler *profiler)
 {
@@ -921,13 +1192,10 @@ process_requests (MonoProfiler *profiler)
 }
 
 static void counters_init (MonoProfiler *profiler);
-static void counters_sample (MonoProfiler *profiler, uint64_t timestamp, gboolean threadless);
+static void counters_sample (MonoProfiler *profiler, uint64_t timestamp);
 
-/*
- * Can be called only at safe callback locations.
- */
 static void
-safe_send (MonoProfiler *profiler, LogBuffer *logbuffer)
+safe_send (MonoProfiler *profiler)
 {
        /* We need the runtime initialized so that we have threads and hazard
         * pointers available. Otherwise, the lock free queue will not work and
@@ -939,33 +1207,102 @@ safe_send (MonoProfiler *profiler, LogBuffer *logbuffer)
        if (!InterlockedRead (&runtime_inited))
                return;
 
-       int cd = logbuffer->call_depth;
+       MonoProfilerThread *thread = PROF_TLS_GET ();
 
-       send_buffer (profiler, TLS_GET (GPtrArray, tlsmethodlist), TLS_GET (LogBuffer, tlsbuffer));
+       buffer_lock ();
 
-       TLS_SET (tlsbuffer, NULL);
-       TLS_SET (tlsmethodlist, NULL);
+       send_buffer (profiler, thread);
+       init_buffer_state (thread);
 
-       init_thread ();
+       buffer_unlock ();
+}
 
-       TLS_GET (LogBuffer, tlsbuffer)->call_depth = cd;
+static void
+send_if_needed (MonoProfiler *prof)
+{
+       if (PROF_TLS_GET ()->buffer->next)
+               safe_send (prof);
 }
 
 static void
-safe_send_threadless (MonoProfiler *prof, LogBuffer *buf)
+safe_send_threadless (MonoProfiler *prof)
 {
+       LogBuffer *buf = PROF_TLS_GET ()->buffer;
+
        for (LogBuffer *iter = buf; iter; iter = iter->next)
                iter->thread_id = 0;
 
-       safe_send (prof, buf);
+       safe_send (prof);
+}
+
+static void
+send_if_needed_threadless (MonoProfiler *prof)
+{
+       if (PROF_TLS_GET ()->buffer->next)
+               safe_send_threadless (prof);
+}
+
+// Assumes that the exclusive lock is held.
+static void
+sync_point_flush (MonoProfiler *prof)
+{
+       g_assert (InterlockedReadPointer (&buffer_rwlock_exclusive) == (gpointer) thread_id () && "Why don't we hold the exclusive lock?");
+
+       MONO_LLS_FOREACH_SAFE (&profiler_thread_list, MonoProfilerThread, thread) {
+               send_buffer (prof, thread);
+               init_buffer_state (thread);
+       } MONO_LLS_FOREACH_SAFE_END
+}
+
+// Assumes that the exclusive lock is held.
+static void
+sync_point_mark (MonoProfiler *prof, MonoProfilerSyncPointType type)
+{
+       g_assert (InterlockedReadPointer (&buffer_rwlock_exclusive) == (gpointer) thread_id () && "Why don't we hold the exclusive lock?");
+
+       ENTER_LOG;
+
+       LogBuffer *logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* type */
+       );
+
+       emit_event (logbuffer, TYPE_META | TYPE_SYNC_POINT);
+       emit_byte (logbuffer, type);
+
+       EXIT_LOG;
+
+       switch (type) {
+       case SYNC_POINT_PERIODIC:
+               safe_send_threadless (prof);
+               break;
+       case SYNC_POINT_WORLD_STOP:
+       case SYNC_POINT_WORLD_START:
+               safe_send (prof);
+               break;
+       default:
+               g_assert_not_reached ();
+               break;
+       }
+}
+
+// Assumes that the exclusive lock is held.
+static void
+sync_point (MonoProfiler *prof, MonoProfilerSyncPointType type)
+{
+       sync_point_flush (prof);
+       sync_point_mark (prof, type);
 }
 
 static int
 gc_reference (MonoObject *obj, MonoClass *klass, uintptr_t size, uintptr_t num, MonoObject **refs, uintptr_t *offsets, void *data)
 {
-       int i;
-       uintptr_t last_offset = 0;
-       //const char *name = mono_class_get_name (klass);
+       /* account for object alignment in the heap */
+       size += 7;
+       size &= ~7;
+
+       ENTER_LOG;
+
        LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
                LEB128_SIZE /* obj */ +
@@ -977,21 +1314,23 @@ gc_reference (MonoObject *obj, MonoClass *klass, uintptr_t size, uintptr_t num,
                        LEB128_SIZE /* ref */
                )
        );
-       emit_byte (logbuffer, TYPE_HEAP_OBJECT | TYPE_HEAP);
+
+       emit_event (logbuffer, TYPE_HEAP_OBJECT | TYPE_HEAP);
        emit_obj (logbuffer, obj);
        emit_ptr (logbuffer, klass);
-       /* account for object alignment in the heap */
-       size += 7;
-       size &= ~7;
        emit_value (logbuffer, size);
        emit_value (logbuffer, num);
-       for (i = 0; i < num; ++i) {
+
+       uintptr_t last_offset = 0;
+
+       for (int i = 0; i < num; ++i) {
                emit_value (logbuffer, offsets [i] - last_offset);
                last_offset = offsets [i];
                emit_obj (logbuffer, refs [i]);
        }
-       //if (num)
-       //      printf ("obj: %p, klass: %s, refs: %d, size: %d\n", obj, name, (int)num, (int)size);
+
+       EXIT_LOG;
+
        return 0;
 }
 
@@ -1004,85 +1343,132 @@ static uint64_t last_hs_time = 0;
 static void
 heap_walk (MonoProfiler *profiler)
 {
-       int do_walk = 0;
-       uint64_t now;
-       LogBuffer *logbuffer;
        if (!do_heap_shot)
                return;
-       logbuffer = ensure_logbuf (
-               EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */
-       );
-       now = current_time ();
-       if (hs_mode_ms && (now - last_hs_time)/1000000 >= hs_mode_ms)
-               do_walk = 1;
+
+       gboolean do_walk = 0;
+       uint64_t now = current_time ();
+
+       if (hs_mode_ms && (now - last_hs_time) / 1000000 >= hs_mode_ms)
+               do_walk = TRUE;
        else if (hs_mode_gc && (gc_count % hs_mode_gc) == 0)
-               do_walk = 1;
+               do_walk = TRUE;
        else if (hs_mode_ondemand)
                do_walk = heapshot_requested;
        else if (!hs_mode_ms && !hs_mode_gc && profiler->last_gc_gen_started == mono_gc_max_generation ())
-               do_walk = 1;
+               do_walk = TRUE;
 
        if (!do_walk)
                return;
+
        heapshot_requested = 0;
-       emit_byte (logbuffer, TYPE_HEAP_START | TYPE_HEAP);
-       emit_time (logbuffer, now);
+
+       ENTER_LOG;
+
+       LogBuffer *logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */
+       );
+
+       emit_event (logbuffer, TYPE_HEAP_START | TYPE_HEAP);
+
+       EXIT_LOG;
+
        mono_gc_walk_heap (0, gc_reference, NULL);
-       logbuffer = ensure_logbuf (
-               EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */
+
+       ENTER_LOG;
+
+       LogBuffer *logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */
        );
+
        now = current_time ();
-       emit_byte (logbuffer, TYPE_HEAP_END | TYPE_HEAP);
-       emit_time (logbuffer, now);
+
+       emit_event (logbuffer, TYPE_HEAP_END | TYPE_HEAP);
+
+       EXIT_LOG;
+
        last_hs_time = now;
 }
 
 static void
-gc_event (MonoProfiler *profiler, MonoGCEvent ev, int generation) {
-       uint64_t now;
+gc_event (MonoProfiler *profiler, MonoGCEvent ev, int generation)
+{
+       ENTER_LOG;
+
        LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
-               LEB128_SIZE /* gc event */ +
-               LEB128_SIZE /* generation */
+               BYTE_SIZE /* gc event */ +
+               BYTE_SIZE /* generation */
        );
-       now = current_time ();
-       ENTER_LOG (logbuffer, "gcevent");
-       emit_byte (logbuffer, TYPE_GC_EVENT | TYPE_GC);
-       emit_time (logbuffer, now);
-       emit_value (logbuffer, ev);
-       emit_value (logbuffer, generation);
-       /* to deal with nested gen1 after gen0 started */
-       if (ev == MONO_GC_EVENT_START) {
+
+       emit_event (logbuffer, TYPE_GC_EVENT | TYPE_GC);
+       emit_byte (logbuffer, ev);
+       emit_byte (logbuffer, generation);
+
+       EXIT_LOG;
+
+       switch (ev) {
+       case MONO_GC_EVENT_START:
+               /* to deal with nested gen1 after gen0 started */
                profiler->last_gc_gen_started = generation;
+
                if (generation == mono_gc_max_generation ())
                        gc_count++;
-       }
-       if (ev == MONO_GC_EVENT_PRE_START_WORLD)
+               break;
+       case MONO_GC_EVENT_PRE_STOP_WORLD_LOCKED:
+               /*
+                * Ensure that no thread can be in the middle of writing to
+                * a buffer when the world stops...
+                */
+               buffer_lock_excl ();
+               break;
+       case MONO_GC_EVENT_POST_STOP_WORLD:
+               /*
+                * ... So that we now have a consistent view of all buffers.
+                * This allows us to flush them. We need to do this because
+                * they may contain object allocation events that need to be
+                * committed to the log file before any object move events
+                * that will be produced during this GC.
+                */
+               sync_point (profiler, SYNC_POINT_WORLD_STOP);
+               break;
+       case MONO_GC_EVENT_PRE_START_WORLD:
                heap_walk (profiler);
-       EXIT_LOG (logbuffer);
-       if (ev == MONO_GC_EVENT_POST_START_WORLD)
-               safe_send (profiler, logbuffer);
-       //printf ("gc event %d for generation %d\n", ev, generation);
+               break;
+       case MONO_GC_EVENT_POST_START_WORLD_UNLOCKED:
+               /*
+                * Similarly, we must now make sure that any object moves
+                * written to the GC thread's buffer are flushed. Otherwise,
+                * object allocation events for certain addresses could come
+                * after the move events that made those addresses available.
+                */
+               sync_point_mark (profiler, SYNC_POINT_WORLD_START);
+
+               /*
+                * Finally, it is safe to allow other threads to write to
+                * their buffers again.
+                */
+               buffer_unlock_excl ();
+               break;
+       default:
+               break;
+       }
 }
 
 static void
-gc_resize (MonoProfiler *profiler, int64_t new_size) {
-       uint64_t now;
+gc_resize (MonoProfiler *profiler, int64_t new_size)
+{
+       ENTER_LOG;
+
        LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
                LEB128_SIZE /* new size */
        );
-       now = current_time ();
-       ENTER_LOG (logbuffer, "gcresize");
-       emit_byte (logbuffer, TYPE_GC_RESIZE | TYPE_GC);
-       emit_time (logbuffer, now);
+
+       emit_event (logbuffer, TYPE_GC_RESIZE | TYPE_GC);
        emit_value (logbuffer, new_size);
-       //printf ("gc resized to %lld\n", new_size);
-       EXIT_LOG (logbuffer);
+
+       EXIT_LOG;
 }
 
 // If you alter MAX_FRAMES, you may need to alter SAMPLE_BLOCK_SIZE too.
@@ -1130,87 +1516,86 @@ emit_bt (MonoProfiler *prof, LogBuffer *logbuffer, FrameData *data)
         */
        if (data->count > num_frames)
                printf ("bad num frames: %d\n", data->count);
-       emit_value (logbuffer, 0); /* flags */
        emit_value (logbuffer, data->count);
        //if (*p != data.count) {
        //      printf ("bad num frames enc at %d: %d -> %d\n", count, data.count, *p); printf ("frames end: %p->%p\n", p, logbuffer->cursor); exit(0);}
        while (data->count) {
-               emit_method_as_ptr (prof, logbuffer, data->methods [--data->count]);
+               emit_method (prof, logbuffer, data->methods [--data->count]);
        }
 }
 
 static void
 gc_alloc (MonoProfiler *prof, MonoObject *obj, MonoClass *klass)
 {
-       uint64_t now;
-       uintptr_t len;
-       int do_bt = (nocalls && InterlockedRead (&runtime_inited) && !notraces)? TYPE_ALLOC_BT: 0;
+       init_thread (TRUE);
+
+       int do_bt = (nocalls && InterlockedRead (&runtime_inited) && !notraces) ? TYPE_ALLOC_BT : 0;
        FrameData data;
-       LogBuffer *logbuffer;
-       len = mono_object_get_size (obj);
+       uintptr_t len = mono_object_get_size (obj);
        /* account for object alignment in the heap */
        len += 7;
        len &= ~7;
+
        if (do_bt)
                collect_bt (&data);
-       logbuffer = ensure_logbuf (
+
+       ENTER_LOG;
+
+       LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
                LEB128_SIZE /* klass */ +
                LEB128_SIZE /* obj */ +
                LEB128_SIZE /* size */ +
                (do_bt ? (
-                       LEB128_SIZE /* flags */ +
                        LEB128_SIZE /* count */ +
                        data.count * (
                                LEB128_SIZE /* method */
                        )
                ) : 0)
        );
-       now = current_time ();
-       ENTER_LOG (logbuffer, "gcalloc");
-       emit_byte (logbuffer, do_bt | TYPE_ALLOC);
-       emit_time (logbuffer, now);
+
+       emit_event (logbuffer, do_bt | TYPE_ALLOC);
        emit_ptr (logbuffer, klass);
        emit_obj (logbuffer, obj);
        emit_value (logbuffer, len);
+
        if (do_bt)
                emit_bt (prof, logbuffer, &data);
-       EXIT_LOG (logbuffer);
-       if (logbuffer->next)
-               safe_send (prof, logbuffer);
+
+       EXIT_LOG;
+
+       send_if_needed (prof);
+
        process_requests (prof);
-       //printf ("gc alloc %s at %p\n", mono_class_get_name (klass), obj);
 }
 
 static void
 gc_moves (MonoProfiler *prof, void **objects, int num)
 {
-       int i;
-       uint64_t now;
+       ENTER_LOG;
+
        LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
                LEB128_SIZE /* num */ +
                num * (
                        LEB128_SIZE /* object */
                )
        );
-       now = current_time ();
-       ENTER_LOG (logbuffer, "gcmove");
-       emit_byte (logbuffer, TYPE_GC_MOVE | TYPE_GC);
-       emit_time (logbuffer, now);
+
+       emit_event (logbuffer, TYPE_GC_MOVE | TYPE_GC);
        emit_value (logbuffer, num);
-       for (i = 0; i < num; ++i)
+
+       for (int i = 0; i < num; ++i)
                emit_obj (logbuffer, objects [i]);
-       //printf ("gc moved %d objects\n", num/2);
-       EXIT_LOG (logbuffer);
+
+       EXIT_LOG;
 }
 
 static void
 gc_roots (MonoProfiler *prof, int num, void **objects, int *root_types, uintptr_t *extra_info)
 {
-       int i;
+       ENTER_LOG;
+
        LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
                LEB128_SIZE /* num */ +
@@ -1221,38 +1606,39 @@ gc_roots (MonoProfiler *prof, int num, void **objects, int *root_types, uintptr_
                        LEB128_SIZE /* extra info */
                )
        );
-       ENTER_LOG (logbuffer, "gcroots");
-       emit_byte (logbuffer, TYPE_HEAP_ROOT | TYPE_HEAP);
+
+       emit_event (logbuffer, TYPE_HEAP_ROOT | TYPE_HEAP);
        emit_value (logbuffer, num);
        emit_value (logbuffer, mono_gc_collection_count (mono_gc_max_generation ()));
-       for (i = 0; i < num; ++i) {
+
+       for (int i = 0; i < num; ++i) {
                emit_obj (logbuffer, objects [i]);
-               emit_value (logbuffer, root_types [i]);
+               emit_byte (logbuffer, root_types [i]);
                emit_value (logbuffer, extra_info [i]);
        }
-       EXIT_LOG (logbuffer);
+
+       EXIT_LOG;
 }
 
 static void
 gc_handle (MonoProfiler *prof, int op, int type, uintptr_t handle, MonoObject *obj)
 {
        int do_bt = nocalls && InterlockedRead (&runtime_inited) && !notraces;
-       uint64_t now;
        FrameData data;
 
        if (do_bt)
                collect_bt (&data);
 
+       ENTER_LOG;
+
        LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
                LEB128_SIZE /* type */ +
                LEB128_SIZE /* handle */ +
                (op == MONO_PROFILER_GC_HANDLE_CREATED ? (
                        LEB128_SIZE /* obj */
                ) : 0) +
                (do_bt ? (
-                       LEB128_SIZE /* flags */ +
                        LEB128_SIZE /* count */ +
                        data.count * (
                                LEB128_SIZE /* method */
@@ -1260,17 +1646,13 @@ gc_handle (MonoProfiler *prof, int op, int type, uintptr_t handle, MonoObject *o
                ) : 0)
        );
 
-       now = current_time ();
-       ENTER_LOG (logbuffer, "gchandle");
-
        if (op == MONO_PROFILER_GC_HANDLE_CREATED)
-               emit_byte (logbuffer, (do_bt ? TYPE_GC_HANDLE_CREATED_BT : TYPE_GC_HANDLE_CREATED) | TYPE_GC);
+               emit_event (logbuffer, (do_bt ? TYPE_GC_HANDLE_CREATED_BT : TYPE_GC_HANDLE_CREATED) | TYPE_GC);
        else if (op == MONO_PROFILER_GC_HANDLE_DESTROYED)
-               emit_byte (logbuffer, (do_bt ? TYPE_GC_HANDLE_DESTROYED_BT : TYPE_GC_HANDLE_DESTROYED) | TYPE_GC);
+               emit_event (logbuffer, (do_bt ? TYPE_GC_HANDLE_DESTROYED_BT : TYPE_GC_HANDLE_DESTROYED) | TYPE_GC);
        else
                g_assert_not_reached ();
 
-       emit_time (logbuffer, now);
        emit_value (logbuffer, type);
        emit_value (logbuffer, handle);
 
@@ -1280,7 +1662,76 @@ gc_handle (MonoProfiler *prof, int op, int type, uintptr_t handle, MonoObject *o
        if (do_bt)
                emit_bt (prof, logbuffer, &data);
 
-       EXIT_LOG (logbuffer);
+       EXIT_LOG;
+
+       process_requests (prof);
+}
+
+static void
+finalize_begin (MonoProfiler *prof)
+{
+       ENTER_LOG;
+
+       LogBuffer *buf = ensure_logbuf (
+               EVENT_SIZE /* event */
+       );
+
+       emit_event (buf, TYPE_GC_FINALIZE_START | TYPE_GC);
+
+       EXIT_LOG;
+
+       process_requests (prof);
+}
+
+static void
+finalize_end (MonoProfiler *prof)
+{
+       ENTER_LOG;
+
+       LogBuffer *buf = ensure_logbuf (
+               EVENT_SIZE /* event */
+       );
+
+       emit_event (buf, TYPE_GC_FINALIZE_END | TYPE_GC);
+
+       EXIT_LOG;
+
+       process_requests (prof);
+}
+
+static void
+finalize_object_begin (MonoProfiler *prof, MonoObject *obj)
+{
+       ENTER_LOG;
+
+       LogBuffer *buf = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* obj */
+       );
+
+       emit_event (buf, TYPE_GC_FINALIZE_OBJECT_START | TYPE_GC);
+       emit_obj (buf, obj);
+
+       EXIT_LOG;
+
+       process_requests (prof);
+}
+
+static void
+finalize_object_end (MonoProfiler *prof, MonoObject *obj)
+{
+       ENTER_LOG;
+
+       LogBuffer *buf = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               LEB128_SIZE /* obj */
+       );
+
+       emit_event (buf, TYPE_GC_FINALIZE_OBJECT_END | TYPE_GC);
+       emit_obj (buf, obj);
+
+       EXIT_LOG;
+
        process_requests (prof);
 }
 
@@ -1323,35 +1774,31 @@ type_name (MonoClass *klass)
 static void
 image_loaded (MonoProfiler *prof, MonoImage *image, int result)
 {
-       uint64_t now;
-       const char *name;
-       int nlen;
-       LogBuffer *logbuffer;
        if (result != MONO_PROFILE_OK)
                return;
-       name = mono_image_get_filename (image);
-       nlen = strlen (name) + 1;
-       logbuffer = ensure_logbuf (
+
+       const char *name = mono_image_get_filename (image);
+       int nlen = strlen (name) + 1;
+
+       ENTER_LOG;
+
+       LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
-               EVENT_SIZE /* type */ +
+               BYTE_SIZE /* type */ +
                LEB128_SIZE /* image */ +
-               LEB128_SIZE /* flags */ +
                nlen /* name */
        );
-       now = current_time ();
-       ENTER_LOG (logbuffer, "image");
-       emit_byte (logbuffer, TYPE_END_LOAD | TYPE_METADATA);
-       emit_time (logbuffer, now);
+
+       emit_event (logbuffer, TYPE_END_LOAD | TYPE_METADATA);
        emit_byte (logbuffer, TYPE_IMAGE);
        emit_ptr (logbuffer, image);
-       emit_value (logbuffer, 0); /* flags */
        memcpy (logbuffer->cursor, name, nlen);
        logbuffer->cursor += nlen;
-       //printf ("loaded image %p (%s)\n", image, name);
-       EXIT_LOG (logbuffer);
-       if (logbuffer->next)
-               safe_send (prof, logbuffer);
+
+       EXIT_LOG;
+
+       send_if_needed (prof);
+
        process_requests (prof);
 
        InterlockedIncrement (&image_loads);
@@ -1362,28 +1809,25 @@ image_unloaded (MonoProfiler *prof, MonoImage *image)
 {
        const char *name = mono_image_get_filename (image);
        int nlen = strlen (name) + 1;
+
+       ENTER_LOG;
+
        LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
-               EVENT_SIZE /* type */ +
+               BYTE_SIZE /* type */ +
                LEB128_SIZE /* image */ +
-               LEB128_SIZE /* flags */ +
                nlen /* name */
        );
-       uint64_t now = current_time ();
 
-       ENTER_LOG (logbuffer, "image-unload");
-       emit_byte (logbuffer, TYPE_END_UNLOAD | TYPE_METADATA);
-       emit_time (logbuffer, now);
+       emit_event (logbuffer, TYPE_END_UNLOAD | TYPE_METADATA);
        emit_byte (logbuffer, TYPE_IMAGE);
        emit_ptr (logbuffer, image);
-       emit_value (logbuffer, 0); /* flags */
        memcpy (logbuffer->cursor, name, nlen);
        logbuffer->cursor += nlen;
-       EXIT_LOG (logbuffer);
 
-       if (logbuffer->next)
-               safe_send (prof, logbuffer);
+       EXIT_LOG;
+
+       send_if_needed (prof);
 
        process_requests (prof);
 
@@ -1398,30 +1842,27 @@ assembly_loaded (MonoProfiler *prof, MonoAssembly *assembly, int result)
 
        char *name = mono_stringify_assembly_name (mono_assembly_get_name (assembly));
        int nlen = strlen (name) + 1;
+
+       ENTER_LOG;
+
        LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
-               EVENT_SIZE /* type */ +
+               BYTE_SIZE /* type */ +
                LEB128_SIZE /* assembly */ +
-               LEB128_SIZE /* flags */ +
                nlen /* name */
        );
-       uint64_t now = current_time ();
 
-       ENTER_LOG (logbuffer, "assembly-load");
-       emit_byte (logbuffer, TYPE_END_LOAD | TYPE_METADATA);
-       emit_time (logbuffer, now);
+       emit_event (logbuffer, TYPE_END_LOAD | TYPE_METADATA);
        emit_byte (logbuffer, TYPE_ASSEMBLY);
        emit_ptr (logbuffer, assembly);
-       emit_value (logbuffer, 0); /* flags */
        memcpy (logbuffer->cursor, name, nlen);
        logbuffer->cursor += nlen;
-       EXIT_LOG (logbuffer);
+
+       EXIT_LOG;
 
        mono_free (name);
 
-       if (logbuffer->next)
-               safe_send (prof, logbuffer);
+       send_if_needed (prof);
 
        process_requests (prof);
 
@@ -1433,30 +1874,27 @@ assembly_unloaded (MonoProfiler *prof, MonoAssembly *assembly)
 {
        char *name = mono_stringify_assembly_name (mono_assembly_get_name (assembly));
        int nlen = strlen (name) + 1;
+
+       ENTER_LOG;
+
        LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
-               EVENT_SIZE /* type */ +
+               BYTE_SIZE /* type */ +
                LEB128_SIZE /* assembly */ +
-               LEB128_SIZE /* flags */ +
                nlen /* name */
        );
-       uint64_t now = current_time ();
 
-       ENTER_LOG (logbuffer, "assembly-unload");
-       emit_byte (logbuffer, TYPE_END_UNLOAD | TYPE_METADATA);
-       emit_time (logbuffer, now);
+       emit_event (logbuffer, TYPE_END_UNLOAD | TYPE_METADATA);
        emit_byte (logbuffer, TYPE_ASSEMBLY);
        emit_ptr (logbuffer, assembly);
-       emit_value (logbuffer, 0); /* flags */
        memcpy (logbuffer->cursor, name, nlen);
        logbuffer->cursor += nlen;
-       EXIT_LOG (logbuffer);
+
+       EXIT_LOG;
 
        mono_free (name);
 
-       if (logbuffer->next)
-               safe_send (prof, logbuffer);
+       send_if_needed (prof);
 
        process_requests (prof);
 
@@ -1466,46 +1904,45 @@ assembly_unloaded (MonoProfiler *prof, MonoAssembly *assembly)
 static void
 class_loaded (MonoProfiler *prof, MonoClass *klass, int result)
 {
-       uint64_t now;
-       char *name;
-       int nlen;
-       MonoImage *image;
-       LogBuffer *logbuffer;
        if (result != MONO_PROFILE_OK)
                return;
+
+       char *name;
+
        if (InterlockedRead (&runtime_inited))
                name = mono_type_get_name (mono_class_get_type (klass));
        else
                name = type_name (klass);
-       nlen = strlen (name) + 1;
-       image = mono_class_get_image (klass);
-       logbuffer = ensure_logbuf (
+
+       int nlen = strlen (name) + 1;
+       MonoImage *image = mono_class_get_image (klass);
+
+       ENTER_LOG;
+
+       LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
-               EVENT_SIZE /* type */ +
+               BYTE_SIZE /* type */ +
                LEB128_SIZE /* klass */ +
                LEB128_SIZE /* image */ +
-               LEB128_SIZE /* flags */ +
                nlen /* name */
        );
-       now = current_time ();
-       ENTER_LOG (logbuffer, "class");
-       emit_byte (logbuffer, TYPE_END_LOAD | TYPE_METADATA);
-       emit_time (logbuffer, now);
+
+       emit_event (logbuffer, TYPE_END_LOAD | TYPE_METADATA);
        emit_byte (logbuffer, TYPE_CLASS);
        emit_ptr (logbuffer, klass);
        emit_ptr (logbuffer, image);
-       emit_value (logbuffer, 0); /* flags */
        memcpy (logbuffer->cursor, name, nlen);
        logbuffer->cursor += nlen;
-       //printf ("loaded class %p (%s)\n", klass, name);
+
+       EXIT_LOG;
+
        if (runtime_inited)
                mono_free (name);
        else
                free (name);
-       EXIT_LOG (logbuffer);
-       if (logbuffer->next)
-               safe_send (prof, logbuffer);
+
+       send_if_needed (prof);
+
        process_requests (prof);
 
        InterlockedIncrement (&class_loads);
@@ -1523,35 +1960,32 @@ class_unloaded (MonoProfiler *prof, MonoClass *klass)
 
        int nlen = strlen (name) + 1;
        MonoImage *image = mono_class_get_image (klass);
+
+       ENTER_LOG;
+
        LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
-               EVENT_SIZE /* type */ +
+               BYTE_SIZE /* type */ +
                LEB128_SIZE /* klass */ +
                LEB128_SIZE /* image */ +
-               LEB128_SIZE /* flags */ +
                nlen /* name */
        );
-       uint64_t now = current_time ();
 
-       ENTER_LOG (logbuffer, "class-unload");
-       emit_byte (logbuffer, TYPE_END_UNLOAD | TYPE_METADATA);
-       emit_time (logbuffer, now);
+       emit_event (logbuffer, TYPE_END_UNLOAD | TYPE_METADATA);
        emit_byte (logbuffer, TYPE_CLASS);
        emit_ptr (logbuffer, klass);
        emit_ptr (logbuffer, image);
-       emit_value (logbuffer, 0); /* flags */
        memcpy (logbuffer->cursor, name, nlen);
        logbuffer->cursor += nlen;
-       EXIT_LOG (logbuffer);
+
+       EXIT_LOG;
 
        if (runtime_inited)
                mono_free (name);
        else
                free (name);
 
-       if (logbuffer->next)
-               safe_send (prof, logbuffer);
+       send_if_needed (prof);
 
        process_requests (prof);
 
@@ -1565,24 +1999,25 @@ static void process_method_enter_coverage (MonoProfiler *prof, MonoMethod *metho
 static void
 method_enter (MonoProfiler *prof, MonoMethod *method)
 {
-       uint64_t now = current_time ();
+#ifndef DISABLE_HELPER_THREAD
+       process_method_enter_coverage (prof, method);
+#endif /* DISABLE_HELPER_THREAD */
+
+       if (PROF_TLS_GET ()->call_depth++ <= max_call_depth) {
+               ENTER_LOG;
+
+               LogBuffer *logbuffer = ensure_logbuf (
+                       EVENT_SIZE /* event */ +
+                       LEB128_SIZE /* method */
+               );
+
+               emit_event (logbuffer, TYPE_ENTER | TYPE_METHOD);
+               emit_method (prof, logbuffer, method);
 
-#ifndef DISABLE_HELPER_THREAD
-       process_method_enter_coverage (prof, method);
-#endif /* DISABLE_HELPER_THREAD */
+               EXIT_LOG;
+       }
 
-       LogBuffer *logbuffer = ensure_logbuf (
-               EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
-               LEB128_SIZE /* method */
-       );
-       if (logbuffer->call_depth++ > max_call_depth)
-               return;
-       ENTER_LOG (logbuffer, "enter");
-       emit_byte (logbuffer, TYPE_ENTER | TYPE_METHOD);
-       emit_time (logbuffer, now);
-       emit_method (prof, logbuffer, method);
-       EXIT_LOG (logbuffer);
+       send_if_needed (prof);
 
        process_requests (prof);
 }
@@ -1590,45 +2025,44 @@ method_enter (MonoProfiler *prof, MonoMethod *method)
 static void
 method_leave (MonoProfiler *prof, MonoMethod *method)
 {
-       uint64_t now;
-       LogBuffer *logbuffer = ensure_logbuf (
-               EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
-               LEB128_SIZE /* method */
-       );
-       if (--logbuffer->call_depth > max_call_depth)
-               return;
-       now = current_time ();
-       ENTER_LOG (logbuffer, "leave");
-       emit_byte (logbuffer, TYPE_LEAVE | TYPE_METHOD);
-       emit_time (logbuffer, now);
-       emit_method (prof, logbuffer, method);
-       EXIT_LOG (logbuffer);
-       if (logbuffer->next)
-               safe_send (prof, logbuffer);
+       if (--PROF_TLS_GET ()->call_depth <= max_call_depth) {
+               ENTER_LOG;
+
+               LogBuffer *logbuffer = ensure_logbuf (
+                       EVENT_SIZE /* event */ +
+                       LEB128_SIZE /* method */
+               );
+
+               emit_event (logbuffer, TYPE_LEAVE | TYPE_METHOD);
+               emit_method (prof, logbuffer, method);
+
+               EXIT_LOG;
+       }
+
+       send_if_needed (prof);
+
        process_requests (prof);
 }
 
 static void
 method_exc_leave (MonoProfiler *prof, MonoMethod *method)
 {
-       uint64_t now;
-       LogBuffer *logbuffer;
-       if (nocalls)
-               return;
-       logbuffer = ensure_logbuf (
-               EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
-               LEB128_SIZE /* method */
-       );
-       if (--logbuffer->call_depth > max_call_depth)
-               return;
-       now = current_time ();
-       ENTER_LOG (logbuffer, "eleave");
-       emit_byte (logbuffer, TYPE_EXC_LEAVE | TYPE_METHOD);
-       emit_time (logbuffer, now);
-       emit_method (prof, logbuffer, method);
-       EXIT_LOG (logbuffer);
+       if (!nocalls && --PROF_TLS_GET ()->call_depth <= max_call_depth) {
+               ENTER_LOG;
+
+               LogBuffer *logbuffer = ensure_logbuf (
+                       EVENT_SIZE /* event */ +
+                       LEB128_SIZE /* method */
+               );
+
+               emit_event (logbuffer, TYPE_EXC_LEAVE | TYPE_METHOD);
+               emit_method (prof, logbuffer, method);
+
+               EXIT_LOG;
+       }
+
+       send_if_needed (prof);
+
        process_requests (prof);
 }
 
@@ -1646,93 +2080,95 @@ method_jitted (MonoProfiler *prof, MonoMethod *method, MonoJitInfo *ji, int resu
 static void
 code_buffer_new (MonoProfiler *prof, void *buffer, int size, MonoProfilerCodeBufferType type, void *data)
 {
-       uint64_t now;
-       int nlen;
        char *name;
-       LogBuffer *logbuffer;
+       int nlen;
+
        if (type == MONO_PROFILER_CODE_BUFFER_SPECIFIC_TRAMPOLINE) {
-               name = (char *)data;
+               name = (char *) data;
                nlen = strlen (name) + 1;
        } else {
                name = NULL;
                nlen = 0;
        }
-       logbuffer = ensure_logbuf (
+
+       ENTER_LOG;
+
+       LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
-               LEB128_SIZE /* type */ +
+               BYTE_SIZE /* type */ +
                LEB128_SIZE /* buffer */ +
                LEB128_SIZE /* size */ +
                (name ? (
                        nlen /* name */
                ) : 0)
        );
-       now = current_time ();
-       ENTER_LOG (logbuffer, "code buffer");
-       emit_byte (logbuffer, TYPE_JITHELPER | TYPE_RUNTIME);
-       emit_time (logbuffer, now);
-       emit_value (logbuffer, type);
+
+       emit_event (logbuffer, TYPE_JITHELPER | TYPE_RUNTIME);
+       emit_byte (logbuffer, type);
        emit_ptr (logbuffer, buffer);
        emit_value (logbuffer, size);
+
        if (name) {
                memcpy (logbuffer->cursor, name, nlen);
                logbuffer->cursor += nlen;
        }
-       EXIT_LOG (logbuffer);
+
+       EXIT_LOG;
+
        process_requests (prof);
 }
 
 static void
 throw_exc (MonoProfiler *prof, MonoObject *object)
 {
-       int do_bt = (nocalls && InterlockedRead (&runtime_inited) && !notraces)? TYPE_EXCEPTION_BT: 0;
-       uint64_t now;
+       int do_bt = (nocalls && InterlockedRead (&runtime_inited) && !notraces) ? TYPE_THROW_BT : 0;
        FrameData data;
-       LogBuffer *logbuffer;
+
        if (do_bt)
                collect_bt (&data);
-       logbuffer = ensure_logbuf (
+
+       ENTER_LOG;
+
+       LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
                LEB128_SIZE /* object */ +
                (do_bt ? (
-                       LEB128_SIZE /* flags */ +
                        LEB128_SIZE /* count */ +
                        data.count * (
                                LEB128_SIZE /* method */
                        )
                ) : 0)
        );
-       now = current_time ();
-       ENTER_LOG (logbuffer, "throw");
-       emit_byte (logbuffer, do_bt | TYPE_EXCEPTION);
-       emit_time (logbuffer, now);
+
+       emit_event (logbuffer, do_bt | TYPE_EXCEPTION);
        emit_obj (logbuffer, object);
+
        if (do_bt)
                emit_bt (prof, logbuffer, &data);
-       EXIT_LOG (logbuffer);
+
+       EXIT_LOG;
+
        process_requests (prof);
 }
 
 static void
 clause_exc (MonoProfiler *prof, MonoMethod *method, int clause_type, int clause_num)
 {
-       uint64_t now;
+       ENTER_LOG;
+
        LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
-               LEB128_SIZE /* clause type */ +
+               BYTE_SIZE /* clause type */ +
                LEB128_SIZE /* clause num */ +
                LEB128_SIZE /* method */
        );
-       now = current_time ();
-       ENTER_LOG (logbuffer, "clause");
-       emit_byte (logbuffer, TYPE_EXCEPTION | TYPE_CLAUSE);
-       emit_time (logbuffer, now);
-       emit_value (logbuffer, clause_type);
+
+       emit_event (logbuffer, TYPE_EXCEPTION | TYPE_CLAUSE);
+       emit_byte (logbuffer, clause_type);
        emit_value (logbuffer, clause_num);
        emit_method (prof, logbuffer, method);
-       EXIT_LOG (logbuffer);
+
+       EXIT_LOG;
 
        process_requests (prof);
 }
@@ -1740,60 +2176,56 @@ clause_exc (MonoProfiler *prof, MonoMethod *method, int clause_type, int clause_
 static void
 monitor_event (MonoProfiler *profiler, MonoObject *object, MonoProfilerMonitorEvent event)
 {
-       int do_bt = (nocalls && InterlockedRead (&runtime_inited) && !notraces && event == MONO_PROFILER_MONITOR_CONTENTION)? TYPE_MONITOR_BT: 0;
-       uint64_t now;
+       int do_bt = (nocalls && InterlockedRead (&runtime_inited) && !notraces && event == MONO_PROFILER_MONITOR_CONTENTION) ? TYPE_MONITOR_BT : 0;
        FrameData data;
-       LogBuffer *logbuffer;
+
        if (do_bt)
                collect_bt (&data);
-       logbuffer = ensure_logbuf (
+
+       ENTER_LOG;
+
+       LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
                LEB128_SIZE /* object */ +
                (do_bt ? (
-                       LEB128_SIZE /* flags */ +
                        LEB128_SIZE /* count */ +
                        data.count * (
                                LEB128_SIZE /* method */
                        )
                ) : 0)
        );
-       now = current_time ();
-       ENTER_LOG (logbuffer, "monitor");
-       emit_byte (logbuffer, (event << 4) | do_bt | TYPE_MONITOR);
-       emit_time (logbuffer, now);
+
+       emit_event (logbuffer, (event << 4) | do_bt | TYPE_MONITOR);
        emit_obj (logbuffer, object);
+
        if (do_bt)
                emit_bt (profiler, logbuffer, &data);
-       EXIT_LOG (logbuffer);
+
+       EXIT_LOG;
+
        process_requests (profiler);
 }
 
 static void
 thread_start (MonoProfiler *prof, uintptr_t tid)
 {
-       //printf ("thread start %p\n", (void*)tid);
-       init_thread ();
+       init_thread (TRUE);
+
+       ENTER_LOG;
 
        LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
-               EVENT_SIZE /* type */ +
-               LEB128_SIZE /* tid */ +
-               LEB128_SIZE /* flags */
+               BYTE_SIZE /* type */ +
+               LEB128_SIZE /* tid */
        );
-       uint64_t now = current_time ();
 
-       ENTER_LOG (logbuffer, "thread-start");
-       emit_byte (logbuffer, TYPE_END_LOAD | TYPE_METADATA);
-       emit_time (logbuffer, now);
+       emit_event (logbuffer, TYPE_END_LOAD | TYPE_METADATA);
        emit_byte (logbuffer, TYPE_THREAD);
        emit_ptr (logbuffer, (void*) tid);
-       emit_value (logbuffer, 0); /* flags */
-       EXIT_LOG (logbuffer);
 
-       if (logbuffer->next)
-               safe_send (prof, logbuffer);
+       EXIT_LOG;
+
+       send_if_needed (prof);
 
        process_requests (prof);
 
@@ -1803,31 +2235,23 @@ thread_start (MonoProfiler *prof, uintptr_t tid)
 static void
 thread_end (MonoProfiler *prof, uintptr_t tid)
 {
-       if (TLS_GET (LogBuffer, tlsbuffer)) {
-               LogBuffer *logbuffer = ensure_logbuf (
-                       EVENT_SIZE /* event */ +
-                       LEB128_SIZE /* time */ +
-                       EVENT_SIZE /* type */ +
-                       LEB128_SIZE /* tid */ +
-                       LEB128_SIZE /* flags */
-               );
-               uint64_t now = current_time ();
+       ENTER_LOG;
+
+       LogBuffer *logbuffer = ensure_logbuf (
+               EVENT_SIZE /* event */ +
+               BYTE_SIZE /* type */ +
+               LEB128_SIZE /* tid */
+       );
 
-               ENTER_LOG (logbuffer, "thread-end");
-               emit_byte (logbuffer, TYPE_END_UNLOAD | TYPE_METADATA);
-               emit_time (logbuffer, now);
-               emit_byte (logbuffer, TYPE_THREAD);
-               emit_ptr (logbuffer, (void*) tid);
-               emit_value (logbuffer, 0); /* flags */
-               EXIT_LOG (logbuffer);
+       emit_event (logbuffer, TYPE_END_UNLOAD | TYPE_METADATA);
+       emit_byte (logbuffer, TYPE_THREAD);
+       emit_ptr (logbuffer, (void*) tid);
 
-               send_buffer (prof, TLS_GET (GPtrArray, tlsmethodlist), logbuffer);
+       EXIT_LOG;
 
-               /* Don't process requests as the thread is detached from the runtime. */
-       }
+       // Don't process requests as the thread is detached from the runtime.
 
-       TLS_SET (tlsbuffer, NULL);
-       TLS_SET (tlsmethodlist, NULL);
+       remove_thread (prof, PROF_TLS_GET (), TRUE);
 
        InterlockedIncrement (&thread_ends);
 }
@@ -1838,25 +2262,21 @@ domain_loaded (MonoProfiler *prof, MonoDomain *domain, int result)
        if (result != MONO_PROFILE_OK)
                return;
 
+       ENTER_LOG;
+
        LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
-               EVENT_SIZE /* type */ +
-               LEB128_SIZE /* domain id */ +
-               LEB128_SIZE /* flags */
+               BYTE_SIZE /* type */ +
+               LEB128_SIZE /* domain id */
        );
-       uint64_t now = current_time ();
 
-       ENTER_LOG (logbuffer, "domain-start");
-       emit_byte (logbuffer, TYPE_END_LOAD | TYPE_METADATA);
-       emit_time (logbuffer, now);
+       emit_event (logbuffer, TYPE_END_LOAD | TYPE_METADATA);
        emit_byte (logbuffer, TYPE_DOMAIN);
        emit_ptr (logbuffer, (void*)(uintptr_t) mono_domain_get_id (domain));
-       emit_value (logbuffer, 0); /* flags */
-       EXIT_LOG (logbuffer);
 
-       if (logbuffer->next)
-               safe_send (prof, logbuffer);
+       EXIT_LOG;
+
+       send_if_needed (prof);
 
        process_requests (prof);
 
@@ -1866,25 +2286,21 @@ domain_loaded (MonoProfiler *prof, MonoDomain *domain, int result)
 static void
 domain_unloaded (MonoProfiler *prof, MonoDomain *domain)
 {
+       ENTER_LOG;
+
        LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
-               EVENT_SIZE /* type */ +
-               LEB128_SIZE /* domain id */ +
-               LEB128_SIZE /* flags */
+               BYTE_SIZE /* type */ +
+               LEB128_SIZE /* domain id */
        );
-       uint64_t now = current_time ();
 
-       ENTER_LOG (logbuffer, "domain-end");
-       emit_byte (logbuffer, TYPE_END_UNLOAD | TYPE_METADATA);
-       emit_time (logbuffer, now);
+       emit_event (logbuffer, TYPE_END_UNLOAD | TYPE_METADATA);
        emit_byte (logbuffer, TYPE_DOMAIN);
        emit_ptr (logbuffer, (void*)(uintptr_t) mono_domain_get_id (domain));
-       emit_value (logbuffer, 0); /* flags */
-       EXIT_LOG (logbuffer);
 
-       if (logbuffer->next)
-               safe_send (prof, logbuffer);
+       EXIT_LOG;
+
+       send_if_needed (prof);
 
        process_requests (prof);
 
@@ -1895,28 +2311,25 @@ static void
 domain_name (MonoProfiler *prof, MonoDomain *domain, const char *name)
 {
        int nlen = strlen (name) + 1;
+
+       ENTER_LOG;
+
        LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
-               EVENT_SIZE /* type */ +
+               BYTE_SIZE /* type */ +
                LEB128_SIZE /* domain id */ +
-               LEB128_SIZE /* flags */ +
                nlen /* name */
        );
-       uint64_t now = current_time ();
 
-       ENTER_LOG (logbuffer, "domain-name");
-       emit_byte (logbuffer, TYPE_METADATA);
-       emit_time (logbuffer, now);
+       emit_event (logbuffer, TYPE_METADATA);
        emit_byte (logbuffer, TYPE_DOMAIN);
        emit_ptr (logbuffer, (void*)(uintptr_t) mono_domain_get_id (domain));
-       emit_value (logbuffer, 0); /* flags */
        memcpy (logbuffer->cursor, name, nlen);
        logbuffer->cursor += nlen;
-       EXIT_LOG (logbuffer);
 
-       if (logbuffer->next)
-               safe_send (prof, logbuffer);
+       EXIT_LOG;
+
+       send_if_needed (prof);
 
        process_requests (prof);
 }
@@ -1924,27 +2337,23 @@ domain_name (MonoProfiler *prof, MonoDomain *domain, const char *name)
 static void
 context_loaded (MonoProfiler *prof, MonoAppContext *context)
 {
+       ENTER_LOG;
+
        LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
-               EVENT_SIZE /* type */ +
+               BYTE_SIZE /* type */ +
                LEB128_SIZE /* context id */ +
-               LEB128_SIZE /* flags */ +
                LEB128_SIZE /* domain id */
        );
-       uint64_t now = current_time ();
 
-       ENTER_LOG (logbuffer, "context-start");
-       emit_byte (logbuffer, TYPE_END_LOAD | TYPE_METADATA);
-       emit_time (logbuffer, now);
+       emit_event (logbuffer, TYPE_END_LOAD | TYPE_METADATA);
        emit_byte (logbuffer, TYPE_CONTEXT);
        emit_ptr (logbuffer, (void*)(uintptr_t) mono_context_get_id (context));
-       emit_value (logbuffer, 0); /* flags */
        emit_ptr (logbuffer, (void*)(uintptr_t) mono_context_get_domain_id (context));
-       EXIT_LOG (logbuffer);
 
-       if (logbuffer->next)
-               safe_send (prof, logbuffer);
+       EXIT_LOG;
+
+       send_if_needed (prof);
 
        process_requests (prof);
 
@@ -1954,27 +2363,23 @@ context_loaded (MonoProfiler *prof, MonoAppContext *context)
 static void
 context_unloaded (MonoProfiler *prof, MonoAppContext *context)
 {
+       ENTER_LOG;
+
        LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
-               EVENT_SIZE /* type */ +
+               BYTE_SIZE /* type */ +
                LEB128_SIZE /* context id */ +
-               LEB128_SIZE /* flags */ +
                LEB128_SIZE /* domain id */
        );
-       uint64_t now = current_time ();
 
-       ENTER_LOG (logbuffer, "context-end");
-       emit_byte (logbuffer, TYPE_END_UNLOAD | TYPE_METADATA);
-       emit_time (logbuffer, now);
+       emit_event (logbuffer, TYPE_END_UNLOAD | TYPE_METADATA);
        emit_byte (logbuffer, TYPE_CONTEXT);
        emit_ptr (logbuffer, (void*)(uintptr_t) mono_context_get_id (context));
-       emit_value (logbuffer, 0); /* flags */
        emit_ptr (logbuffer, (void*)(uintptr_t) mono_context_get_domain_id (context));
-       EXIT_LOG (logbuffer);
 
-       if (logbuffer->next)
-               safe_send (prof, logbuffer);
+       EXIT_LOG;
+
+       send_if_needed (prof);
 
        process_requests (prof);
 
@@ -1985,29 +2390,25 @@ static void
 thread_name (MonoProfiler *prof, uintptr_t tid, const char *name)
 {
        int len = strlen (name) + 1;
-       uint64_t now;
-       LogBuffer *logbuffer;
-       logbuffer = ensure_logbuf (
+
+       ENTER_LOG;
+
+       LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
-               EVENT_SIZE /* type */ +
+               BYTE_SIZE /* type */ +
                LEB128_SIZE /* tid */ +
-               LEB128_SIZE /* flags */ +
                len /* name */
        );
-       now = current_time ();
-       ENTER_LOG (logbuffer, "tname");
-       emit_byte (logbuffer, TYPE_METADATA);
-       emit_time (logbuffer, now);
+
+       emit_event (logbuffer, TYPE_METADATA);
        emit_byte (logbuffer, TYPE_THREAD);
        emit_ptr (logbuffer, (void*)tid);
-       emit_value (logbuffer, 0); /* flags */
        memcpy (logbuffer->cursor, name, len);
        logbuffer->cursor += len;
-       EXIT_LOG (logbuffer);
 
-       if (logbuffer->next)
-               safe_send (prof, logbuffer);
+       EXIT_LOG;
+
+       send_if_needed (prof);
 
        process_requests (prof);
 }
@@ -2022,7 +2423,7 @@ typedef struct {
 typedef struct {
        MonoLockFreeQueueNode node;
        MonoProfiler *prof;
-       uint64_t elapsed;
+       uint64_t time;
        uintptr_t tid;
        void *ip;
        int count;
@@ -2079,8 +2480,6 @@ mono_sample_hit (MonoProfiler *profiler, unsigned char *ip, void *context)
 
        InterlockedIncrement (&sample_hits);
 
-       uint64_t now = current_time ();
-
        SampleHit *sample = (SampleHit *) mono_lock_free_queue_dequeue (&profiler->sample_reuse_queue);
 
        if (!sample) {
@@ -2101,16 +2500,14 @@ mono_sample_hit (MonoProfiler *profiler, unsigned char *ip, void *context)
        sample->count = 0;
        mono_stack_walk_async_safe (&async_walk_stack, context, sample);
 
-       uintptr_t elapsed = (now - profiler->startup_time) / 10000;
-
-       sample->elapsed = elapsed;
+       sample->time = current_time ();
        sample->tid = thread_id ();
        sample->ip = ip;
 
        if (do_debug) {
                int len;
                char buf [256];
-               snprintf (buf, sizeof (buf), "hit at %p in thread %p after %llu ms\n", ip, (void *) thread_id (), (unsigned long long int) elapsed / 100);
+               snprintf (buf, sizeof (buf), "hit at %p in thread %p after %llu ms\n", ip, (void *) sample->tid, (unsigned long long int) ((sample->time - profiler->startup_time) / 10000 / 100));
                len = strlen (buf);
                ign_res (write (2, buf, len));
        }
@@ -2177,46 +2574,50 @@ add_code_pointer (uintptr_t ip)
 static void
 dump_ubin (const char *filename, uintptr_t load_addr, uint64_t offset, uintptr_t size)
 {
-       uint64_t now;
-       LogBuffer *logbuffer;
-       int len;
-       len = strlen (filename) + 1;
-       now = current_time ();
-       logbuffer = ensure_logbuf (
+       int len = strlen (filename) + 1;
+
+       ENTER_LOG;
+
+       LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */ +
                LEB128_SIZE /* load address */ +
                LEB128_SIZE /* offset */ +
                LEB128_SIZE /* size */ +
                nlen /* file name */
        );
-       emit_byte (logbuffer, TYPE_SAMPLE | TYPE_SAMPLE_UBIN);
-       emit_time (logbuffer, now);
+
+       emit_event (logbuffer, TYPE_SAMPLE | TYPE_SAMPLE_UBIN);
        emit_svalue (logbuffer, load_addr);
        emit_uvalue (logbuffer, offset);
        emit_uvalue (logbuffer, size);
        memcpy (logbuffer->cursor, filename, len);
        logbuffer->cursor += len;
+
+       EXIT_LOG;
 }
 #endif
 
 static void
 dump_usym (const char *name, uintptr_t value, uintptr_t size)
 {
-       LogBuffer *logbuffer;
-       int len;
-       len = strlen (name) + 1;
-       logbuffer = ensure_logbuf (
+       int len = strlen (name) + 1;
+
+       ENTER_LOG;
+
+       LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
                LEB128_SIZE /* value */ +
                LEB128_SIZE /* size */ +
                len /* name */
        );
-       emit_byte (logbuffer, TYPE_SAMPLE | TYPE_SAMPLE_USYM);
+
+       emit_event (logbuffer, TYPE_SAMPLE | TYPE_SAMPLE_USYM);
        emit_ptr (logbuffer, (void*)value);
        emit_value (logbuffer, size);
        memcpy (logbuffer->cursor, name, len);
        logbuffer->cursor += len;
+
+       EXIT_LOG;
 }
 
 /* ELF code crashes on some systems. */
@@ -2592,7 +2993,6 @@ setup_perf_map (PerfData *perf)
 static void
 dump_perf_hits (MonoProfiler *prof, void *buf, int size)
 {
-       LogBuffer *logbuffer;
        int count = 1;
        int mbt_count = 0;
        void *end = (char*)buf + size;
@@ -2612,10 +3012,12 @@ dump_perf_hits (MonoProfiler *prof, void *buf, int size)
                /*ip = (void*)s->ip;
                printf ("sample: %d, size: %d, ip: %p (%s), timestamp: %llu, nframes: %llu\n",
                        s->h.type, s->h.size, ip, symbol_for (ip), s->timestamp, s->nframes);*/
-               logbuffer = ensure_logbuf (
+
+               ENTER_LOG;
+
+               LogBuffer *logbuffer = ensure_logbuf (
                        EVENT_SIZE /* event */ +
-                       LEB128_SIZE /* type */ +
-                       LEB128_SIZE /* time */ +
+                       BYTE_SIZE /* type */ +
                        LEB128_SIZE /* tid */ +
                        LEB128_SIZE /* count */ +
                        count * (
@@ -2623,14 +3025,12 @@ dump_perf_hits (MonoProfiler *prof, void *buf, int size)
                        ) +
                        LEB128_SIZE /* managed count */ +
                        mbt_count * (
-                               LEB128_SIZE /* method */ +
-                               LEB128_SIZE /* il offset */ +
-                               LEB128_SIZE /* native offset */
+                               LEB128_SIZE /* method */
                        )
                );
-               emit_byte (logbuffer, TYPE_SAMPLE | TYPE_SAMPLE_HIT);
-               emit_value (logbuffer, sample_type);
-               emit_uvalue (logbuffer, s->timestamp - prof->startup_time);
+
+               emit_event (logbuffer, TYPE_SAMPLE | TYPE_SAMPLE_HIT);
+               emit_byte (logbuffer, sample_type);
                /*
                 * No useful thread ID to write here, since throughout the
                 * profiler we use pthread_self () but the ID we get from
@@ -2639,9 +3039,12 @@ dump_perf_hits (MonoProfiler *prof, void *buf, int size)
                emit_ptr (logbuffer, 0);
                emit_value (logbuffer, count);
                emit_ptr (logbuffer, (void*)(uintptr_t)s->ip);
-               add_code_pointer (s->ip);
                /* no support here yet for the managed backtrace */
                emit_uvalue (logbuffer, mbt_count);
+
+               EXIT_LOG;
+
+               add_code_pointer (s->ip);
                buf = (char*)buf + s->h.size;
                samples++;
        }
@@ -2833,10 +3236,9 @@ counters_init (MonoProfiler *profiler)
 }
 
 static void
-counters_emit (MonoProfiler *profiler, gboolean threadless)
+counters_emit (MonoProfiler *profiler)
 {
        MonoCounterAgent *agent;
-       LogBuffer *logbuffer;
        int len = 0;
        int size =
                EVENT_SIZE /* event */ +
@@ -2855,9 +3257,9 @@ counters_emit (MonoProfiler *profiler, gboolean threadless)
                size +=
                        LEB128_SIZE /* section */ +
                        strlen (mono_counter_get_name (agent->counter)) + 1 /* name */ +
-                       LEB128_SIZE /* type */ +
-                       LEB128_SIZE /* unit */ +
-                       LEB128_SIZE /* variance */ +
+                       BYTE_SIZE /* type */ +
+                       BYTE_SIZE /* unit */ +
+                       BYTE_SIZE /* variance */ +
                        LEB128_SIZE /* index */
                ;
 
@@ -2869,11 +3271,13 @@ counters_emit (MonoProfiler *profiler, gboolean threadless)
                return;
        }
 
-       logbuffer = ensure_logbuf (size);
+       ENTER_LOG;
 
-       ENTER_LOG (logbuffer, "counters");
-       emit_byte (logbuffer, TYPE_SAMPLE_COUNTERS_DESC | TYPE_SAMPLE);
+       LogBuffer *logbuffer = ensure_logbuf (size);
+
+       emit_event (logbuffer, TYPE_SAMPLE_COUNTERS_DESC | TYPE_SAMPLE);
        emit_value (logbuffer, len);
+
        for (agent = counters; agent; agent = agent->next) {
                const char *name;
 
@@ -2883,29 +3287,24 @@ counters_emit (MonoProfiler *profiler, gboolean threadless)
                name = mono_counter_get_name (agent->counter);
                emit_value (logbuffer, mono_counter_get_section (agent->counter));
                emit_string (logbuffer, name, strlen (name) + 1);
-               emit_value (logbuffer, mono_counter_get_type (agent->counter));
-               emit_value (logbuffer, mono_counter_get_unit (agent->counter));
-               emit_value (logbuffer, mono_counter_get_variance (agent->counter));
+               emit_byte (logbuffer, mono_counter_get_type (agent->counter));
+               emit_byte (logbuffer, mono_counter_get_unit (agent->counter));
+               emit_byte (logbuffer, mono_counter_get_variance (agent->counter));
                emit_value (logbuffer, agent->index);
 
                agent->emitted = 1;
        }
-       EXIT_LOG (logbuffer);
 
-       if (threadless)
-               safe_send_threadless (profiler, logbuffer);
-       else
-               safe_send (profiler, logbuffer);
+       EXIT_LOG;
 
        mono_os_mutex_unlock (&counters_mutex);
 }
 
 static void
-counters_sample (MonoProfiler *profiler, uint64_t timestamp, gboolean threadless)
+counters_sample (MonoProfiler *profiler, uint64_t timestamp)
 {
        MonoCounterAgent *agent;
        MonoCounter *counter;
-       LogBuffer *logbuffer;
        int type;
        int buffer_size;
        void *buffer;
@@ -2914,7 +3313,7 @@ counters_sample (MonoProfiler *profiler, uint64_t timestamp, gboolean threadless
        if (!counters_initialized)
                return;
 
-       counters_emit (profiler, threadless);
+       counters_emit (profiler);
 
        buffer_size = 8;
        buffer = calloc (1, buffer_size);
@@ -2922,14 +3321,13 @@ counters_sample (MonoProfiler *profiler, uint64_t timestamp, gboolean threadless
        mono_os_mutex_lock (&counters_mutex);
 
        size =
-               EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */
+               EVENT_SIZE /* event */
        ;
 
        for (agent = counters; agent; agent = agent->next) {
                size +=
                        LEB128_SIZE /* index */ +
-                       LEB128_SIZE /* type */ +
+                       BYTE_SIZE /* type */ +
                        mono_counter_get_size (agent->counter) /* value */
                ;
        }
@@ -2938,11 +3336,12 @@ counters_sample (MonoProfiler *profiler, uint64_t timestamp, gboolean threadless
                LEB128_SIZE /* stop marker */
        ;
 
-       logbuffer = ensure_logbuf (size);
+       ENTER_LOG;
+
+       LogBuffer *logbuffer = ensure_logbuf (size);
+
+       emit_event_time (logbuffer, TYPE_SAMPLE_COUNTERS | TYPE_SAMPLE, timestamp);
 
-       ENTER_LOG (logbuffer, "counters");
-       emit_byte (logbuffer, TYPE_SAMPLE_COUNTERS | TYPE_SAMPLE);
-       emit_uvalue (logbuffer, timestamp);
        for (agent = counters; agent; agent = agent->next) {
                size_t size;
 
@@ -2977,7 +3376,7 @@ counters_sample (MonoProfiler *profiler, uint64_t timestamp, gboolean threadless
                }
 
                emit_uvalue (logbuffer, agent->index);
-               emit_uvalue (logbuffer, type);
+               emit_byte (logbuffer, type);
                switch (type) {
                case MONO_COUNTER_INT:
 #if SIZEOF_VOID_P == 4
@@ -3024,12 +3423,8 @@ counters_sample (MonoProfiler *profiler, uint64_t timestamp, gboolean threadless
        free (buffer);
 
        emit_value (logbuffer, 0);
-       EXIT_LOG (logbuffer);
 
-       if (threadless)
-               safe_send_threadless (profiler, logbuffer);
-       else
-               safe_send (profiler, logbuffer);
+       EXIT_LOG;
 
        mono_os_mutex_unlock (&counters_mutex);
 }
@@ -3050,10 +3445,9 @@ struct _PerfCounterAgent {
 static PerfCounterAgent *perfcounters = NULL;
 
 static void
-perfcounters_emit (MonoProfiler *profiler, gboolean threadless)
+perfcounters_emit (MonoProfiler *profiler)
 {
        PerfCounterAgent *pcagent;
-       LogBuffer *logbuffer;
        int len = 0;
        int size =
                EVENT_SIZE /* event */ +
@@ -3068,9 +3462,9 @@ perfcounters_emit (MonoProfiler *profiler, gboolean threadless)
                        LEB128_SIZE /* section */ +
                        strlen (pcagent->category_name) + 1 /* category name */ +
                        strlen (pcagent->name) + 1 /* name */ +
-                       LEB128_SIZE /* type */ +
-                       LEB128_SIZE /* unit */ +
-                       LEB128_SIZE /* variance */ +
+                       BYTE_SIZE /* type */ +
+                       BYTE_SIZE /* unit */ +
+                       BYTE_SIZE /* variance */ +
                        LEB128_SIZE /* index */
                ;
 
@@ -3080,11 +3474,13 @@ perfcounters_emit (MonoProfiler *profiler, gboolean threadless)
        if (!len)
                return;
 
-       logbuffer = ensure_logbuf (size);
+       ENTER_LOG;
+
+       LogBuffer *logbuffer = ensure_logbuf (size);
 
-       ENTER_LOG (logbuffer, "perfcounters");
-       emit_byte (logbuffer, TYPE_SAMPLE_COUNTERS_DESC | TYPE_SAMPLE);
+       emit_event (logbuffer, TYPE_SAMPLE_COUNTERS_DESC | TYPE_SAMPLE);
        emit_value (logbuffer, len);
+
        for (pcagent = perfcounters; pcagent; pcagent = pcagent->next) {
                if (pcagent->emitted)
                        continue;
@@ -3092,19 +3488,15 @@ perfcounters_emit (MonoProfiler *profiler, gboolean threadless)
                emit_value (logbuffer, MONO_COUNTER_PERFCOUNTERS);
                emit_string (logbuffer, pcagent->category_name, strlen (pcagent->category_name) + 1);
                emit_string (logbuffer, pcagent->name, strlen (pcagent->name) + 1);
-               emit_value (logbuffer, MONO_COUNTER_LONG);
-               emit_value (logbuffer, MONO_COUNTER_RAW);
-               emit_value (logbuffer, MONO_COUNTER_VARIABLE);
+               emit_byte (logbuffer, MONO_COUNTER_LONG);
+               emit_byte (logbuffer, MONO_COUNTER_RAW);
+               emit_byte (logbuffer, MONO_COUNTER_VARIABLE);
                emit_value (logbuffer, pcagent->index);
 
                pcagent->emitted = 1;
        }
-       EXIT_LOG (logbuffer);
 
-       if (threadless)
-               safe_send_threadless (profiler, logbuffer);
-       else
-               safe_send (profiler, logbuffer);
+       EXIT_LOG;
 }
 
 static gboolean
@@ -3141,10 +3533,9 @@ perfcounters_foreach (char *category_name, char *name, unsigned char type, gint6
 }
 
 static void
-perfcounters_sample (MonoProfiler *profiler, uint64_t timestamp, gboolean threadless)
+perfcounters_sample (MonoProfiler *profiler, uint64_t timestamp)
 {
        PerfCounterAgent *pcagent;
-       LogBuffer *logbuffer;
        int size;
 
        if (!counters_initialized)
@@ -3158,11 +3549,10 @@ perfcounters_sample (MonoProfiler *profiler, uint64_t timestamp, gboolean thread
 
        mono_perfcounter_foreach (perfcounters_foreach, perfcounters);
 
-       perfcounters_emit (profiler, threadless);
+       perfcounters_emit (profiler);
 
        size =
-               EVENT_SIZE /* event */ +
-               LEB128_SIZE /* time */
+               EVENT_SIZE /* event */
        ;
 
        for (pcagent = perfcounters; pcagent; pcagent = pcagent->next) {
@@ -3171,7 +3561,7 @@ perfcounters_sample (MonoProfiler *profiler, uint64_t timestamp, gboolean thread
 
                size +=
                        LEB128_SIZE /* index */ +
-                       LEB128_SIZE /* type */ +
+                       BYTE_SIZE /* type */ +
                        LEB128_SIZE /* value */
                ;
        }
@@ -3180,44 +3570,36 @@ perfcounters_sample (MonoProfiler *profiler, uint64_t timestamp, gboolean thread
                LEB128_SIZE /* stop marker */
        ;
 
-       logbuffer = ensure_logbuf (size);
+       ENTER_LOG;
+
+       LogBuffer *logbuffer = ensure_logbuf (size);
+
+       emit_event_time (logbuffer, TYPE_SAMPLE_COUNTERS | TYPE_SAMPLE, timestamp);
 
-       ENTER_LOG (logbuffer, "perfcounters");
-       emit_byte (logbuffer, TYPE_SAMPLE_COUNTERS | TYPE_SAMPLE);
-       emit_uvalue (logbuffer, timestamp);
        for (pcagent = perfcounters; pcagent; pcagent = pcagent->next) {
                if (pcagent->deleted || !pcagent->updated)
                        continue;
                emit_uvalue (logbuffer, pcagent->index);
-               emit_uvalue (logbuffer, MONO_COUNTER_LONG);
+               emit_byte (logbuffer, MONO_COUNTER_LONG);
                emit_svalue (logbuffer, pcagent->value);
 
                pcagent->updated = 0;
        }
 
        emit_value (logbuffer, 0);
-       EXIT_LOG (logbuffer);
 
-       if (threadless)
-               safe_send_threadless (profiler, logbuffer);
-       else
-               safe_send (profiler, logbuffer);
+       EXIT_LOG;
 
        mono_os_mutex_unlock (&counters_mutex);
 }
 
 static void
-counters_and_perfcounters_sample (MonoProfiler *prof, gboolean threadless)
+counters_and_perfcounters_sample (MonoProfiler *prof)
 {
-       static uint64_t start = -1;
-       uint64_t now;
-
-       if (start == -1)
-               start = current_time ();
+       uint64_t now = current_time ();
 
-       now = current_time ();
-       counters_sample (prof, (now - start) / 1000/ 1000, threadless);
-       perfcounters_sample (prof, (now - start) / 1000/ 1000, threadless);
+       counters_sample (prof, now);
+       perfcounters_sample (prof, now);
 }
 
 #define COVERAGE_DEBUG(x) if (debug_coverage) {x}
@@ -3235,20 +3617,18 @@ static gboolean coverage_initialized = FALSE;
 static GPtrArray *coverage_data = NULL;
 static int previous_offset = 0;
 
-typedef struct _MethodNode MethodNode;
-struct _MethodNode {
+typedef struct {
        MonoLockFreeQueueNode node;
        MonoMethod *method;
-};
+} MethodNode;
 
-typedef struct _CoverageEntry CoverageEntry;
-struct _CoverageEntry {
+typedef struct {
        int offset;
        int counter;
        char *filename;
        int line;
        int column;
-};
+} CoverageEntry;
 
 static void
 free_coverage_entry (gpointer data, gpointer userdata)
@@ -3332,7 +3712,6 @@ build_method_buffer (gpointer key, gpointer value, gpointer userdata)
        MonoImage *image;
        char *class_name;
        const char *image_name, *method_name, *sig, *first_filename;
-       LogBuffer *logbuffer;
        guint i;
 
        previous_offset = 0;
@@ -3358,7 +3737,9 @@ build_method_buffer (gpointer key, gpointer value, gpointer userdata)
        sig = sig ? sig : "";
        method_name = method_name ? method_name : "";
 
-       logbuffer = ensure_logbuf (
+       ENTER_LOG;
+
+       LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
                strlen (image_name) + 1 /* image name */ +
                strlen (class_name) + 1 /* class name */ +
@@ -3369,9 +3750,8 @@ build_method_buffer (gpointer key, gpointer value, gpointer userdata)
                LEB128_SIZE /* method id */ +
                LEB128_SIZE /* entries */
        );
-       ENTER_LOG (logbuffer, "coverage-methods");
 
-       emit_byte (logbuffer, TYPE_COVERAGE_METHOD | TYPE_COVERAGE);
+       emit_event (logbuffer, TYPE_COVERAGE_METHOD | TYPE_COVERAGE);
        emit_string (logbuffer, image_name, strlen (image_name) + 1);
        emit_string (logbuffer, class_name, strlen (class_name) + 1);
        emit_string (logbuffer, method_name, strlen (method_name) + 1);
@@ -3382,13 +3762,16 @@ build_method_buffer (gpointer key, gpointer value, gpointer userdata)
        emit_uvalue (logbuffer, method_id);
        emit_value (logbuffer, coverage_data->len);
 
-       EXIT_LOG (logbuffer);
-       safe_send (prof, logbuffer);
+       EXIT_LOG;
+
+       send_if_needed (prof);
 
        for (i = 0; i < coverage_data->len; i++) {
                CoverageEntry *entry = (CoverageEntry *)coverage_data->pdata[i];
 
-               logbuffer = ensure_logbuf (
+               ENTER_LOG;
+
+               LogBuffer *logbuffer = ensure_logbuf (
                        EVENT_SIZE /* event */ +
                        LEB128_SIZE /* method id */ +
                        LEB128_SIZE /* offset */ +
@@ -3396,17 +3779,17 @@ build_method_buffer (gpointer key, gpointer value, gpointer userdata)
                        LEB128_SIZE /* line */ +
                        LEB128_SIZE /* column */
                );
-               ENTER_LOG (logbuffer, "coverage-statement");
 
-               emit_byte (logbuffer, TYPE_COVERAGE_STATEMENT | TYPE_COVERAGE);
+               emit_event (logbuffer, TYPE_COVERAGE_STATEMENT | TYPE_COVERAGE);
                emit_uvalue (logbuffer, method_id);
                emit_uvalue (logbuffer, entry->offset);
                emit_uvalue (logbuffer, entry->counter);
                emit_uvalue (logbuffer, entry->line);
                emit_uvalue (logbuffer, entry->column);
 
-               EXIT_LOG (logbuffer);
-               safe_send (prof, logbuffer);
+               EXIT_LOG;
+
+               send_if_needed (prof);
        }
 
        method_id++;
@@ -3444,7 +3827,6 @@ build_class_buffer (gpointer key, gpointer value, gpointer userdata)
        const char *assembly_name;
        int number_of_methods, partially_covered;
        guint fully_covered;
-       LogBuffer *logbuffer;
 
        image = mono_class_get_image (klass);
        assembly_name = mono_image_get_name (image);
@@ -3456,7 +3838,9 @@ build_class_buffer (gpointer key, gpointer value, gpointer userdata)
        /* We don't handle partial covered yet */
        partially_covered = 0;
 
-       logbuffer = ensure_logbuf (
+       ENTER_LOG;
+
+       LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
                strlen (assembly_name) + 1 /* assembly name */ +
                strlen (class_name) + 1 /* class name */ +
@@ -3465,16 +3849,16 @@ build_class_buffer (gpointer key, gpointer value, gpointer userdata)
                LEB128_SIZE /* partially covered */
        );
 
-       ENTER_LOG (logbuffer, "coverage-class");
-       emit_byte (logbuffer, TYPE_COVERAGE_CLASS | TYPE_COVERAGE);
+       emit_event (logbuffer, TYPE_COVERAGE_CLASS | TYPE_COVERAGE);
        emit_string (logbuffer, assembly_name, strlen (assembly_name) + 1);
        emit_string (logbuffer, class_name, strlen (class_name) + 1);
        emit_uvalue (logbuffer, number_of_methods);
        emit_uvalue (logbuffer, fully_covered);
        emit_uvalue (logbuffer, partially_covered);
-       EXIT_LOG (logbuffer);
 
-       safe_send (prof, logbuffer);
+       EXIT_LOG;
+
+       send_if_needed (prof);
 
        g_free (class_name);
 }
@@ -3500,7 +3884,6 @@ build_assembly_buffer (gpointer key, gpointer value, gpointer userdata)
        MonoAssembly *assembly = (MonoAssembly *)value;
        MonoProfiler *prof = (MonoProfiler *)userdata;
        MonoImage *image = mono_assembly_get_image (assembly);
-       LogBuffer *logbuffer;
        const char *name, *guid, *filename;
        int number_of_methods = 0, partially_covered = 0;
        guint fully_covered = 0;
@@ -3515,7 +3898,9 @@ build_assembly_buffer (gpointer key, gpointer value, gpointer userdata)
 
        get_coverage_for_image (image, &number_of_methods, &fully_covered, &partially_covered);
 
-       logbuffer = ensure_logbuf (
+       ENTER_LOG;
+
+       LogBuffer *logbuffer = ensure_logbuf (
                EVENT_SIZE /* event */ +
                strlen (name) + 1 /* name */ +
                strlen (guid) + 1 /* guid */ +
@@ -3525,17 +3910,17 @@ build_assembly_buffer (gpointer key, gpointer value, gpointer userdata)
                LEB128_SIZE /* partially covered */
        );
 
-       ENTER_LOG (logbuffer, "coverage-assemblies");
-       emit_byte (logbuffer, TYPE_COVERAGE_ASSEMBLY | TYPE_COVERAGE);
+       emit_event (logbuffer, TYPE_COVERAGE_ASSEMBLY | TYPE_COVERAGE);
        emit_string (logbuffer, name, strlen (name) + 1);
        emit_string (logbuffer, guid, strlen (guid) + 1);
        emit_string (logbuffer, filename, strlen (filename) + 1);
        emit_uvalue (logbuffer, number_of_methods);
        emit_uvalue (logbuffer, fully_covered);
        emit_uvalue (logbuffer, partially_covered);
-       EXIT_LOG (logbuffer);
 
-       safe_send (prof, logbuffer);
+       EXIT_LOG;
+
+       send_if_needed (prof);
 }
 
 static void
@@ -3882,7 +4267,7 @@ log_shutdown (MonoProfiler *prof)
 
        in_shutdown = 1;
 #ifndef DISABLE_HELPER_THREAD
-       counters_and_perfcounters_sample (prof, FALSE);
+       counters_and_perfcounters_sample (prof);
 
        dump_coverage (prof);
 
@@ -3900,11 +4285,16 @@ log_shutdown (MonoProfiler *prof)
        }
 #endif
 
-       if (TLS_GET (LogBuffer, tlsbuffer))
-               send_buffer (prof, TLS_GET (GPtrArray, tlsmethodlist), TLS_GET (LogBuffer, tlsbuffer));
-
-       TLS_SET (tlsbuffer, NULL);
-       TLS_SET (tlsmethodlist, NULL);
+       /*
+        * Ensure that we empty the LLS completely, even if some nodes are
+        * not immediately removed upon calling mono_lls_remove (), by
+        * iterating until the head is NULL.
+        */
+       while (profiler_thread_list.head) {
+               MONO_LLS_FOREACH_SAFE (&profiler_thread_list, MonoProfilerThread, thread) {
+                       remove_thread (prof, thread, FALSE);
+               } MONO_LLS_FOREACH_SAFE_END
+       }
 
        InterlockedWrite (&prof->run_dumper_thread, 0);
        mono_os_sem_post (&prof->dumper_queue_sem);
@@ -3918,6 +4308,18 @@ log_shutdown (MonoProfiler *prof)
 
        cleanup_reusable_samples (prof);
 
+       /*
+        * Pump the entire hazard free queue to make sure that anything we allocated
+        * in the profiler will be freed. If we don't do this, the runtime could get
+        * around to freeing some items after the profiler has been unloaded, which
+        * would mean calling into functions in the profiler library, leading to a
+        * crash.
+        */
+       mono_thread_hazardous_try_free_all ();
+
+       g_assert (!InterlockedRead (&buffer_rwlock_count) && "Why is the reader count still non-zero?");
+       g_assert (!InterlockedReadPointer (&buffer_rwlock_exclusive) && "Why does someone still hold the exclusive lock?");
+
 #if defined (HAVE_SYS_ZLIB)
        if (prof->gzfile)
                gzclose (prof->gzfile);
@@ -3946,6 +4348,9 @@ log_shutdown (MonoProfiler *prof)
                mono_os_mutex_destroy (&coverage_mutex);
        }
 
+       PROF_TLS_FREE ();
+
+       free (prof->args);
        free (prof);
 }
 
@@ -4020,11 +4425,12 @@ helper_thread (void* arg)
        int command_socket;
        int len;
        char buf [64];
-       MonoThread *thread = NULL;
 
        mono_threads_attach_tools_thread ();
        mono_native_thread_set_name (mono_native_thread_id_get (), "Profiler helper");
 
+       init_thread (FALSE);
+
        //fprintf (stderr, "Server listening\n");
        command_socket = -1;
        while (1) {
@@ -4055,7 +4461,13 @@ helper_thread (void* arg)
                }
 #endif
 
-               counters_and_perfcounters_sample (prof, TRUE);
+               counters_and_perfcounters_sample (prof);
+
+               buffer_lock_excl ();
+
+               sync_point (prof, SYNC_POINT_PERIODIC);
+
+               buffer_unlock_excl ();
 
                tv.tv_sec = 1;
                tv.tv_usec = 0;
@@ -4072,8 +4484,6 @@ helper_thread (void* arg)
                if (FD_ISSET (prof->pipes [0], &rfds)) {
                        char c;
                        read (prof->pipes [0], &c, 1);
-                       if (thread)
-                               mono_thread_detach (thread);
                        if (do_debug)
                                fprintf (stderr, "helper shutdown\n");
 #if USE_PERF_EVENTS
@@ -4087,7 +4497,7 @@ helper_thread (void* arg)
                                }
                        }
 #endif
-                       safe_send_threadless (prof, ensure_logbuf (0));
+                       safe_send_threadless (prof);
                        return NULL;
                }
 #if USE_PERF_EVENTS
@@ -4098,7 +4508,7 @@ helper_thread (void* arg)
                                        continue;
                                if (FD_ISSET (perf_data [i].perf_fd, &rfds)) {
                                        read_perf_mmap (prof, i);
-                                       safe_send_threadless (prof, ensure_logbuf (0));
+                                       send_if_needed_threadless (prof);
                                }
                        }
                }
@@ -4113,18 +4523,10 @@ helper_thread (void* arg)
                                continue;
                        }
                        buf [len] = 0;
-                       if (strcmp (buf, "heapshot\n") == 0) {
+                       if (strcmp (buf, "heapshot\n") == 0 && hs_mode_ondemand) {
+                               // Rely on the finalization callbacks invoking process_requests ().
                                heapshot_requested = 1;
-                               //fprintf (stderr, "perform heapshot\n");
-                               if (InterlockedRead (&runtime_inited) && !thread) {
-                                       thread = mono_thread_attach (mono_get_root_domain ());
-                                       /*fprintf (stderr, "attached\n");*/
-                               }
-                               if (thread) {
-                                       process_requests (prof);
-                                       mono_thread_detach (thread);
-                                       thread = NULL;
-                               }
+                               mono_gc_finalize_notify ();
                        }
                        continue;
                }
@@ -4186,30 +4588,39 @@ start_helper_thread (MonoProfiler* prof)
 }
 #endif
 
+static void
+free_writer_entry (gpointer p)
+{
+       mono_lock_free_free (p, WRITER_ENTRY_BLOCK_SIZE);
+}
+
 static gboolean
 handle_writer_queue_entry (MonoProfiler *prof)
 {
        WriterQueueEntry *entry;
 
        if ((entry = (WriterQueueEntry *) mono_lock_free_queue_dequeue (&prof->writer_queue))) {
-               LogBuffer *method_buffer = NULL;
-               gboolean new_methods = FALSE;
+               if (!entry->methods)
+                       goto no_methods;
 
-               if (entry->methods->len)
-                       method_buffer = create_buffer ();
+               LogBuffer *buf = NULL;
 
                /*
                 * Encode the method events in a temporary log buffer that we
                 * flush to disk before the main buffer, ensuring that all
                 * methods have metadata emitted before they're referenced.
+                *
+                * We use a 'proper' thread-local buffer for this as opposed
+                * to allocating and freeing a buffer by hand because the call
+                * to mono_method_full_name () below may trigger class load
+                * events when it retrieves the signature of the method. So a
+                * thread-local buffer needs to exist when such events occur.
                 */
                for (guint i = 0; i < entry->methods->len; i++) {
-                       MethodInfo *info = (MethodInfo *)g_ptr_array_index (entry->methods, i);
+                       MethodInfo *info = (MethodInfo *) g_ptr_array_index (entry->methods, i);
 
                        if (mono_conc_hashtable_lookup (prof->method_table, info->method))
-                               continue;
-
-                       new_methods = TRUE;
+                               goto free_info; // This method already has metadata emitted.
 
                        /*
                         * Other threads use this hash table to get a general
@@ -4230,41 +4641,39 @@ handle_writer_queue_entry (MonoProfiler *prof)
                        void *cstart = info->ji ? mono_jit_info_get_code_start (info->ji) : NULL;
                        int csize = info->ji ? mono_jit_info_get_code_size (info->ji) : 0;
 
-                       method_buffer = ensure_logbuf_inner (method_buffer,
+                       buf = ensure_logbuf_unsafe (
                                EVENT_SIZE /* event */ +
-                               LEB128_SIZE /* time */ +
                                LEB128_SIZE /* method */ +
                                LEB128_SIZE /* start */ +
                                LEB128_SIZE /* size */ +
                                nlen /* name */
                        );
 
-                       emit_byte (method_buffer, TYPE_JIT | TYPE_METHOD);
-                       emit_time (method_buffer, info->time);
-                       emit_method_inner (method_buffer, info->method);
-                       emit_ptr (method_buffer, cstart);
-                       emit_value (method_buffer, csize);
+                       emit_event_time (buf, TYPE_JIT | TYPE_METHOD, info->time);
+                       emit_method_inner (buf, info->method);
+                       emit_ptr (buf, cstart);
+                       emit_value (buf, csize);
 
-                       memcpy (method_buffer->cursor, name, nlen);
-                       method_buffer->cursor += nlen;
+                       memcpy (buf->cursor, name, nlen);
+                       buf->cursor += nlen;
 
                        mono_free (name);
+
+               free_info:
                        free (info);
                }
 
                g_ptr_array_free (entry->methods, TRUE);
 
-               if (new_methods) {
-                       for (LogBuffer *iter = method_buffer; iter; iter = iter->next)
-                               iter->thread_id = 0;
-
-                       dump_buffer (prof, method_buffer);
-               } else if (method_buffer)
-                       free_buffer (method_buffer, method_buffer->size);
+               if (buf) {
+                       dump_buffer_threadless (prof, buf);
+                       init_buffer_state (PROF_TLS_GET ());
+               }
 
+       no_methods:
                dump_buffer (prof, entry->buffer);
 
-               mono_thread_hazardous_try_free (entry, free);
+               mono_thread_hazardous_try_free (entry, free_writer_entry);
 
                return TRUE;
        }
@@ -4282,6 +4691,8 @@ writer_thread (void *arg)
 
        dump_header (prof);
 
+       MonoProfilerThread *thread = init_thread (FALSE);
+
        while (InterlockedRead (&prof->run_writer_thread)) {
                mono_os_sem_wait (&prof->writer_queue_sem, MONO_SEM_FLAGS_NONE);
                handle_writer_queue_entry (prof);
@@ -4290,6 +4701,9 @@ writer_thread (void *arg)
        /* Drain any remaining entries on shutdown. */
        while (handle_writer_queue_entry (prof));
 
+       free_buffer (thread->buffer, thread->buffer->size);
+       deinit_thread (thread);
+
        mono_thread_info_detach ();
 
        return NULL;
@@ -4324,8 +4738,8 @@ handle_dumper_queue_entry (MonoProfiler *prof)
                        void *address = sample->frames [i].base_address;
 
                        if (!method) {
-                               g_assert (domain);
-                               g_assert (address);
+                               g_assert (domain && "What happened to the domain pointer?");
+                               g_assert (address && "What happened to the instruction pointer?");
 
                                MonoJitInfo *ji = mono_jit_info_table_find (domain, (char *) address);
 
@@ -4334,10 +4748,9 @@ handle_dumper_queue_entry (MonoProfiler *prof)
                        }
                }
 
-               LogBuffer *logbuffer = ensure_logbuf (
+               LogBuffer *logbuffer = ensure_logbuf_unsafe (
                        EVENT_SIZE /* event */ +
-                       LEB128_SIZE /* type */ +
-                       LEB128_SIZE /* time */ +
+                       BYTE_SIZE /* type */ +
                        LEB128_SIZE /* tid */ +
                        LEB128_SIZE /* count */ +
                        1 * (
@@ -4345,15 +4758,12 @@ handle_dumper_queue_entry (MonoProfiler *prof)
                        ) +
                        LEB128_SIZE /* managed count */ +
                        sample->count * (
-                               LEB128_SIZE /* method */ +
-                               LEB128_SIZE /* il offset */ +
-                               LEB128_SIZE /* native offset */
+                               LEB128_SIZE /* method */
                        )
                );
 
-               emit_byte (logbuffer, TYPE_SAMPLE | TYPE_SAMPLE_HIT);
-               emit_value (logbuffer, sample_type);
-               emit_uvalue (logbuffer, prof->startup_time + sample->elapsed * 10000);
+               emit_event_time (logbuffer, TYPE_SAMPLE | TYPE_SAMPLE_HIT, sample->time);
+               emit_byte (logbuffer, sample_type);
                emit_ptr (logbuffer, (void *) sample->tid);
                emit_value (logbuffer, 1);
 
@@ -4366,18 +4776,14 @@ handle_dumper_queue_entry (MonoProfiler *prof)
                /* new in data version 6 */
                emit_uvalue (logbuffer, sample->count);
 
-               for (int i = 0; i < sample->count; ++i) {
+               for (int i = 0; i < sample->count; ++i)
                        emit_method (prof, logbuffer, sample->frames [i].method);
-                       emit_svalue (logbuffer, 0); /* il offset will always be 0 from now on */
-                       emit_svalue (logbuffer, sample->frames [i].offset);
-               }
 
                mono_thread_hazardous_try_free (sample, reuse_sample_hit);
 
                dump_unmanaged_coderefs (prof);
 
-               if (logbuffer->next)
-                       safe_send_threadless (prof, logbuffer);
+               send_if_needed_threadless (prof);
        }
 
        return FALSE;
@@ -4391,6 +4797,8 @@ dumper_thread (void *arg)
        mono_threads_attach_tools_thread ();
        mono_native_thread_set_name (mono_native_thread_id_get (), "Profiler dumper");
 
+       MonoProfilerThread *thread = init_thread (FALSE);
+
        while (InterlockedRead (&prof->run_dumper_thread)) {
                mono_os_sem_wait (&prof->dumper_queue_sem, MONO_SEM_FLAGS_NONE);
                handle_dumper_queue_entry (prof);
@@ -4399,7 +4807,8 @@ dumper_thread (void *arg)
        /* Drain any remaining entries on shutdown. */
        while (handle_dumper_queue_entry (prof));
 
-       safe_send_threadless (prof, ensure_logbuf (0));
+       safe_send_threadless (prof);
+       deinit_thread (thread);
 
        mono_thread_info_detach ();
 
@@ -4417,6 +4826,8 @@ start_dumper_thread (MonoProfiler* prof)
 static void
 runtime_initialized (MonoProfiler *profiler)
 {
+       InterlockedWrite (&runtime_inited, 1);
+
 #ifndef DISABLE_HELPER_THREAD
        if (hs_mode_ondemand || need_helper_thread) {
                if (!start_helper_thread (profiler))
@@ -4427,23 +4838,40 @@ runtime_initialized (MonoProfiler *profiler)
        start_writer_thread (profiler);
        start_dumper_thread (profiler);
 
-       InterlockedWrite (&runtime_inited, 1);
+       mono_counters_register ("Sample hits", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &sample_hits);
+       mono_counters_register ("Sample flushes", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &sample_flushes);
+       mono_counters_register ("Sample events allocated", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &sample_allocations);
+       mono_counters_register ("Log buffers allocated", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &buffer_allocations);
+       mono_counters_register ("Thread start events", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &thread_starts);
+       mono_counters_register ("Thread stop events", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &thread_ends);
+       mono_counters_register ("Domain load events", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &domain_loads);
+       mono_counters_register ("Domain unload events", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &domain_unloads);
+       mono_counters_register ("Context load events", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &context_loads);
+       mono_counters_register ("Context unload events", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &context_unloads);
+       mono_counters_register ("Assembly load events", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &assembly_loads);
+       mono_counters_register ("Assembly unload events", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &assembly_unloads);
+       mono_counters_register ("Image load events", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &image_loads);
+       mono_counters_register ("Image unload events", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &image_unloads);
+       mono_counters_register ("Class load events", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &class_loads);
+       mono_counters_register ("Class unload events", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &class_unloads);
+
 #ifndef DISABLE_HELPER_THREAD
        counters_init (profiler);
-       counters_sample (profiler, 0, FALSE);
+       counters_sample (profiler, 0);
 #endif
        /* ensure the main thread data and startup are available soon */
-       safe_send (profiler, ensure_logbuf (0));
+       safe_send (profiler);
 }
 
 static MonoProfiler*
-create_profiler (const char *filename, GPtrArray *filters)
+create_profiler (const char *args, const char *filename, GPtrArray *filters)
 {
        MonoProfiler *prof;
        char *nf;
        int force_delete = 0;
        prof = (MonoProfiler *)calloc (1, sizeof (MonoProfiler));
 
+       prof->args = pstrdup (args);
        prof->command_port = command_port;
        if (filename && *filename == '-') {
                force_delete = 1;
@@ -4485,7 +4913,7 @@ create_profiler (const char *filename, GPtrArray *filters)
                prof->gzfile = gzdopen (fileno (prof->file), "wb");
 #endif
 #if USE_PERF_EVENTS
-       if (sample_type && !do_mono_sample)
+       if (sample_type && sample_freq && !do_mono_sample)
                need_helper_thread = setup_perf_event ();
        if (!perf_data) {
                /* FIXME: warn if different freq or sample type */
@@ -4520,6 +4948,12 @@ create_profiler (const char *filename, GPtrArray *filters)
 
 #endif
 
+       g_assert (sizeof (WriterQueueEntry) * 2 < LOCK_FREE_ALLOC_SB_USABLE_SIZE (WRITER_ENTRY_BLOCK_SIZE));
+
+       // FIXME: We should free this stuff too.
+       mono_lock_free_allocator_init_size_class (&prof->writer_entry_size_class, sizeof (WriterQueueEntry), WRITER_ENTRY_BLOCK_SIZE);
+       mono_lock_free_allocator_init_allocator (&prof->writer_entry_allocator, &prof->writer_entry_size_class);
+
        mono_lock_free_queue_init (&prof->writer_queue);
        mono_os_sem_init (&prof->writer_queue_sem, 0);
 
@@ -4728,27 +5162,10 @@ mono_profiler_startup (const char *desc)
                MONO_PROFILE_ENTER_LEAVE|MONO_PROFILE_JIT_COMPILATION|MONO_PROFILE_EXCEPTIONS|
                MONO_PROFILE_MONITOR_EVENTS|MONO_PROFILE_MODULE_EVENTS|MONO_PROFILE_GC_ROOTS|
                MONO_PROFILE_INS_COVERAGE|MONO_PROFILE_APPDOMAIN_EVENTS|MONO_PROFILE_CONTEXT_EVENTS|
-               MONO_PROFILE_ASSEMBLY_EVENTS;
+               MONO_PROFILE_ASSEMBLY_EVENTS|MONO_PROFILE_GC_FINALIZATION;
 
        max_allocated_sample_hits = mono_cpu_count () * 1000;
 
-       mono_counters_register ("Sample hits", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &sample_hits);
-       mono_counters_register ("Sample flushes", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &sample_flushes);
-       mono_counters_register ("Sample events allocated", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &sample_allocations);
-       mono_counters_register ("Log buffers allocated", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &buffer_allocations);
-       mono_counters_register ("Thread start events", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &thread_starts);
-       mono_counters_register ("Thread stop events", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &thread_ends);
-       mono_counters_register ("Domain load events", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &domain_loads);
-       mono_counters_register ("Domain unload events", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &domain_unloads);
-       mono_counters_register ("Context load events", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &context_loads);
-       mono_counters_register ("Context unload events", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &context_unloads);
-       mono_counters_register ("Assembly load events", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &assembly_loads);
-       mono_counters_register ("Assembly unload events", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &assembly_unloads);
-       mono_counters_register ("Image load events", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &image_loads);
-       mono_counters_register ("Image unload events", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &image_unloads);
-       mono_counters_register ("Class load events", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &class_loads);
-       mono_counters_register ("Class unload events", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &class_unloads);
-
        p = desc;
        if (strncmp (p, "log", 3))
                usage (1);
@@ -4932,17 +5349,24 @@ mono_profiler_startup (const char *desc)
 
        utils_init (fast_time);
 
-       prof = create_profiler (filename, filters);
-       if (!prof)
+       PROF_TLS_INIT ();
+
+       prof = create_profiler (desc, filename, filters);
+       if (!prof) {
+               PROF_TLS_FREE ();
                return;
+       }
 
-       init_thread ();
+       mono_lls_init (&profiler_thread_list, NULL);
+
+       init_thread (TRUE);
 
        mono_profiler_install (prof, log_shutdown);
        mono_profiler_install_gc (gc_event, gc_resize);
        mono_profiler_install_allocation (gc_alloc);
        mono_profiler_install_gc_moves (gc_moves);
        mono_profiler_install_gc_roots (gc_handle, gc_roots);
+       mono_profiler_install_gc_finalize (finalize_begin, finalize_object_begin, finalize_object_end, finalize_end);
        mono_profiler_install_appdomain (NULL, domain_loaded, domain_unloaded, NULL);
        mono_profiler_install_appdomain_name (domain_name);
        mono_profiler_install_context (context_loaded, context_unloaded);
@@ -4960,14 +5384,11 @@ mono_profiler_startup (const char *desc)
        if (do_coverage)
                mono_profiler_install_coverage_filter (coverage_filter);
 
-       if (do_mono_sample && sample_type == SAMPLE_CYCLES && !only_counters) {
+       if (do_mono_sample && sample_type == SAMPLE_CYCLES && sample_freq && !only_counters) {
                events |= MONO_PROFILE_STATISTICAL;
                mono_profiler_set_statistical_mode (sampling_mode, sample_freq);
                mono_profiler_install_statistical (mono_sample_hit);
        }
 
        mono_profiler_set_events ((MonoProfileFlags)events);
-
-       TLS_INIT (tlsbuffer);
-       TLS_INIT (tlsmethodlist);
 }
index ecb0e43b82334160ce788b255733b12902fce6ae..5649d8be76abed29521a5437651c5383f2040dfc 100644 (file)
@@ -3,10 +3,14 @@
 
 #define BUF_ID 0x4D504C01
 #define LOG_HEADER_ID 0x4D505A01
-#define LOG_VERSION_MAJOR 0
-#define LOG_VERSION_MINOR 4
-#define LOG_DATA_VERSION 12
+#define LOG_VERSION_MAJOR 1
+#define LOG_VERSION_MINOR 0
+#define LOG_DATA_VERSION 13
 /*
+ * Changes in major/minor versions:
+ * version 1.0: removed sysid field from header
+ *              added args, arch, os fields to header
+ *
  * Changes in data versions:
  * version 2: added offsets in heap walk
  * version 3: added GC roots
                added TYPE_GC_HANDLE_{CREATED,DESTROYED}_BT
                TYPE_JIT events are no longer guaranteed to have code start/size info (can be zero)
  * version 12: added MONO_COUNTER_PROFILER
+ * version 13: added MONO_GC_EVENT_{PRE_STOP_WORLD_LOCKED,POST_START_WORLD_UNLOCKED}
+               added TYPE_META + TYPE_SYNC_POINT
+               removed il and native offset in TYPE_SAMPLE_HIT
+               methods in backtraces are now encoded as proper method pointers
+               removed flags in backtrace format
+               removed flags in metadata events
+               changed the following fields to a single byte rather than leb128
+                   TYPE_GC_EVENT: event_type, generation
+                   TYPE_HEAP_ROOT: root_type
+                   TYPE_JITHELPER: type
+                   TYPE_SAMPLE_HIT: sample_type
+                   TYPE_CLAUSE: clause_type
+                   TYPE_SAMPLE_COUNTERS_DESC: type, unit, variance
+                   TYPE_SAMPLE_COUNTERS: type
+               added time fields to all events that were missing one
+                   TYPE_HEAP_OBJECT
+                   TYPE_HEAP_ROOT
+                   TYPE_SAMPLE_USYM
+                   TYPE_SAMPLE_COUNTERS_DESC
+                   TYPE_COVERAGE_METHOD
+                   TYPE_COVERAGE_STATEMENT
+                   TYPE_COVERAGE_CLASS
+                   TYPE_COVERAGE_ASSEMBLY
+               moved the time field in TYPE_SAMPLE_HIT to right after the event byte, now encoded as a regular time field
+               changed the time field in TYPE_SAMPLE_COUNTERS to be encoded as a regular time field (in nanoseconds)
+               added TYPE_GC_FINALIZE_{START,END,OBJECT_START,OBJECT_END}
  */
 
 enum {
@@ -40,6 +70,7 @@ enum {
        TYPE_SAMPLE,
        TYPE_RUNTIME,
        TYPE_COVERAGE,
+       TYPE_META,
        /* extended type for TYPE_HEAP */
        TYPE_HEAP_START  = 0 << 4,
        TYPE_HEAP_END    = 1 << 4,
@@ -48,13 +79,6 @@ enum {
        /* extended type for TYPE_METADATA */
        TYPE_END_LOAD     = 2 << 4,
        TYPE_END_UNLOAD   = 4 << 4,
-       /* metadata type byte for TYPE_METADATA */
-       TYPE_CLASS     = 1,
-       TYPE_IMAGE     = 2,
-       TYPE_ASSEMBLY  = 3,
-       TYPE_DOMAIN    = 4,
-       TYPE_THREAD    = 5,
-       TYPE_CONTEXT   = 6,
        /* extended type for TYPE_GC */
        TYPE_GC_EVENT  = 1 << 4,
        TYPE_GC_RESIZE = 2 << 4,
@@ -63,15 +87,19 @@ enum {
        TYPE_GC_HANDLE_DESTROYED    = 5 << 4,
        TYPE_GC_HANDLE_CREATED_BT   = 6 << 4,
        TYPE_GC_HANDLE_DESTROYED_BT = 7 << 4,
+       TYPE_GC_FINALIZE_START = 8 << 4,
+       TYPE_GC_FINALIZE_END = 9 << 4,
+       TYPE_GC_FINALIZE_OBJECT_START = 10 << 4,
+       TYPE_GC_FINALIZE_OBJECT_END = 11 << 4,
        /* extended type for TYPE_METHOD */
        TYPE_LEAVE     = 1 << 4,
        TYPE_ENTER     = 2 << 4,
        TYPE_EXC_LEAVE = 3 << 4,
        TYPE_JIT       = 4 << 4,
        /* extended type for TYPE_EXCEPTION */
-       TYPE_THROW        = 0 << 4,
-       TYPE_CLAUSE       = 1 << 4,
-       TYPE_EXCEPTION_BT = 1 << 7,
+       TYPE_THROW_NO_BT = 0 << 7,
+       TYPE_THROW_BT    = 1 << 7,
+       TYPE_CLAUSE      = 1 << 4,
        /* extended type for TYPE_ALLOC */
        TYPE_ALLOC_NO_BT  = 0 << 4,
        TYPE_ALLOC_BT     = 1 << 4,
@@ -91,9 +119,27 @@ enum {
        TYPE_COVERAGE_METHOD   = 1 << 4,
        TYPE_COVERAGE_STATEMENT = 2 << 4,
        TYPE_COVERAGE_CLASS = 3 << 4,
+       /* extended type for TYPE_META */
+       TYPE_SYNC_POINT = 0 << 4,
        TYPE_END
 };
 
+enum {
+       /* metadata type byte for TYPE_METADATA */
+       TYPE_CLASS    = 1,
+       TYPE_IMAGE    = 2,
+       TYPE_ASSEMBLY = 3,
+       TYPE_DOMAIN   = 4,
+       TYPE_THREAD   = 5,
+       TYPE_CONTEXT  = 6,
+};
+
+typedef enum {
+       SYNC_POINT_PERIODIC,
+       SYNC_POINT_WORLD_STOP,
+       SYNC_POINT_WORLD_START
+} MonoProfilerSyncPointType;
+
 // Sampling sources
 // Unless you have compiled with --enable-perf-events, only SAMPLE_CYCLES is available
 enum {
index 753024dcf72963e30c7ebef03da79e54b7cdc7e0..c3e14e4af89065ae8683cd821e6d155251eab515 100644 (file)
@@ -418,7 +418,7 @@ uintptr_t
 process_id (void)
 {
 #ifdef HOST_WIN32
-       return 0; /* FIXME */
+       return GetCurrentProcessId ();
 #else
        return (uintptr_t)getpid ();
 #endif
index d29b91d37015dfbdf727caff0bed4016d99d3843..d996be700ed98c014ff39b94fb94630f3d26af22 100644 (file)
@@ -1126,10 +1126,7 @@ major_get_and_reset_num_major_objects_marked (void)
 
 /* gcc 4.2.1 from xcode4 crashes on sgen_card_table_get_card_address () when this is enabled */
 #if defined(PLATFORM_MACOSX)
-#define GCC_VERSION (__GNUC__ * 10000 \
-                               + __GNUC_MINOR__ * 100 \
-                               + __GNUC_PATCHLEVEL__)
-#if GCC_VERSION <= 40300
+#if MONO_GNUC_VERSION <= 40300
 #undef PREFETCH_CARDS
 #endif
 #endif
index b4d9d0ad8666a1939bfd5a5ef04657a2832a2859..41e4a9b9a4c918db35c8df0c01968b8dec3eb3e3 100644 (file)
@@ -466,7 +466,9 @@ BASE_TEST_CS_SRC_UNIVERSAL=         \
        pinvoke_ppcf.cs \
        pinvoke_ppcd.cs \
        bug-29585.cs    \
-       priority.cs
+       priority.cs     \
+       abort-cctor.cs  \
+       reference-loader.cs
 
 if INSTALL_MOBILE_STATIC
 BASE_TEST_CS_SRC= \
@@ -799,18 +801,22 @@ endif
 # but that need to be compiled
 PREREQ_IL_SRC=event-il.il module-cctor.il
 PREREQ_CS_SRC=
-PREREQ_IL_DLL_SRC=event-il.il module-cctor.il
-PREREQ_CS_DLL_SRC=
+PREREQ_IL_DLL_SRC=
+PREREQ_CS_DLL_SRC=TestingReferenceAssembly.cs TestingReferenceReferenceAssembly.cs
 
-PREREQSI_IL=$(PREREQ_IL_SRC:.il=.exe)
-PREREQSI_CS=$(PREREQ_CS_SRC:.cs=.exe)
+PREREQSI_IL=$(PREREQ_IL_SRC:.il=.exe) \
+       $(PREREQ_IL_DLL_SRC:.il=.dll)
+PREREQSI_CS=$(PREREQ_CS_SRC:.cs=.exe) \
+       $(PREREQ_CS_DLL_SRC:.cs=.dll)
 TESTSI_CS=$(TEST_CS_SRC:.cs=.exe)
 TESTSI_IL=$(TEST_IL_SRC:.il=.exe)
 TESTBS=$(BENCHSRC:.cs=.exe)
 STRESS_TESTS=$(STRESS_TESTS_SRC:.cs=.exe)
 
-PREREQSI_IL_AOT=$(PREREQ_IL_SRC:.il=.exe$(PLATFORM_AOT_SUFFIX))
-PREREQSI_CS_AOT=$(PREREQ_CS_SRC:.cs=.exe$(PLATFORM_AOT_SUFFIX))
+PREREQSI_IL_AOT=$(PREREQ_IL_SRC:.il=.exe$(PLATFORM_AOT_SUFFIX)) \
+               $(PREREQ_IL_DLL_SRC:.il=.dll$(PLATFORM_AOT_SUFFIX))
+PREREQSI_CS_AOT=$(PREREQ_CS_SRC:.cs=.exe$(PLATFORM_AOT_SUFFIX)) \
+               $(PREREQ_CS_DLL_SRC:.cs=.dll$(PLATFORM_AOT_SUFFIX))
 
 EXTRA_DIST=test-driver test-runner.cs $(TEST_CS_SRC_DIST) $(TEST_IL_SRC) \
        $(BENCHSRC) $(STRESS_TESTS_SRC) stress-runner.pl $(PREREQ_IL_SRC) $(PREREQ_CS_SRC)
@@ -831,6 +837,12 @@ endif
 %.exe: %.cs $(TEST_DRIVER_DEPEND)
        $(MCS) -r:System.dll -r:System.Xml.dll -r:System.Core.dll -r:TestDriver.dll $(TEST_DRIVER_HARD_KILL_FEATURE) -out:$@ $<
 
+%.dll: %.cs
+       $(MCS) -r:System.dll -target:library -out:$@ $<
+
+TestingReferenceReferenceAssembly.dll: TestingReferenceReferenceAssembly.cs TestingReferenceAssembly.dll
+       $(MCS) -r:TestingReferenceAssembly.dll -target:library -out:$@ $<
+
 %.exe$(PLATFORM_AOT_SUFFIX): %.exe 
        $(RUNTIME) $(AOT_BUILD_FLAGS) $<
 
diff --git a/mono/tests/TestingReferenceAssembly.cs b/mono/tests/TestingReferenceAssembly.cs
new file mode 100644 (file)
index 0000000..e68a2c8
--- /dev/null
@@ -0,0 +1,7 @@
+using System.Runtime.CompilerServices;
+
+[assembly: ReferenceAssemblyAttribute]
+
+public class X {
+       public int Y;
+}
diff --git a/mono/tests/TestingReferenceReferenceAssembly.cs b/mono/tests/TestingReferenceReferenceAssembly.cs
new file mode 100644 (file)
index 0000000..0acb6f1
--- /dev/null
@@ -0,0 +1,7 @@
+// An assembly that refereces the TestingReferenceAssembly
+
+class Z : X {
+       public Z () {
+               Y = 1;
+       }
+}
diff --git a/mono/tests/abort-cctor.cs b/mono/tests/abort-cctor.cs
new file mode 100644 (file)
index 0000000..34f8780
--- /dev/null
@@ -0,0 +1,332 @@
+using System;
+using System.Diagnostics;
+using System.Threading;
+using System.Runtime.CompilerServices;
+
+class Driver
+{
+       public static ManualResetEvent mre1 = new ManualResetEvent (false);
+       public static ManualResetEvent mre2 = new ManualResetEvent (false);
+
+       class StaticConstructor1
+       {
+               internal static bool gotToEnd, caughtException;
+               static StaticConstructor1 ()
+               {
+                       try {
+                               Console.WriteLine ("StaticConstructor1.StaticConstructor1 (1)");
+                               Driver.mre1.Set ();
+                               var sw = Stopwatch.StartNew ();
+                               Thread.Sleep (1000);
+                               sw.Stop ();
+                               typeof (string).GetMethods ();
+                               //XXX we assume that if we slept less than 900ms we got aborted
+                               if (sw.ElapsedMilliseconds < 900)
+                                       throw new Exception ("Bad abort broke our sleep");
+                               Console.WriteLine ("StaticConstructor1.StaticConstructor1 (2) waited {0}", sw.ElapsedMilliseconds);
+                               gotToEnd = true;
+                       } catch (Exception e) {
+                               caughtException = true;
+                               throw;
+                       }
+               }
+
+               public static void Init ()
+               {
+                       Console.WriteLine ("StaticConstructor1.Init");
+               }
+       }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       static void IsStaticConstructor1Viable () {
+               new StaticConstructor1 ();
+               Console.WriteLine ("Did it get to the end? {0} Did it catch an exception {1}", StaticConstructor1.gotToEnd, StaticConstructor1.caughtException);
+               if (!StaticConstructor1.gotToEnd) /* the TAE must not land during a .cctor */
+                       Environment.Exit (1);
+               if (StaticConstructor1.caughtException)
+                       Environment.Exit (1);
+                       
+       }
+
+       static void Test1 ()
+       {
+               Console.WriteLine ("Test 1:");
+
+               Driver.mre1.Reset ();
+               Driver.mre2.Reset ();
+
+               Thread thread = new Thread (() => {
+                       try {
+                               StaticConstructor1.Init ();
+                       } catch (Exception e) {
+                               Console.WriteLine ("StaticConstructor1::init caught exception {0}", e);
+
+                               if (!(e is ThreadAbortException))
+                                       throw;
+                       }
+               });
+
+               thread.Start ();
+
+               Driver.mre1.WaitOne ();
+
+               // The ThreadAbortException should land while in
+               // the StaticConstructor1.cctor. The exception should
+               // be queued, and be rethrown when exiting the cctor.
+               thread.Abort ();
+
+               thread.Join ();
+
+               //is StaticConstructor1 viable?
+               try {
+                       IsStaticConstructor1Viable ();
+                       Console.WriteLine ("StaticConstructor1 is viable"); /* a TAE doesn't make a type unusable */
+               } catch (TypeInitializationException  e) {
+                       Console.WriteLine ("StaticConstructor1 not viable");
+                       Environment.Exit (1);
+               }
+       }
+
+       class StaticConstructor2Exception : Exception {}
+
+       class StaticConstructor2
+       {
+               static StaticConstructor2 ()
+               {
+                       Console.WriteLine ("StaticConstructor2.StaticConstructor2 (1)");
+                       Driver.mre1.Set ();
+                       throw new StaticConstructor2Exception ();
+                       /* Unreachable */
+                       Driver.mre2.Set ();
+                       Console.WriteLine ("StaticConstructor2.StaticConstructor2 (2)");
+               }
+
+               public static void Init ()
+               {
+                       Console.WriteLine ("StaticConstructor2.Init");
+               }
+       }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       static void IsStaticConstructor2Viable () {
+               new StaticConstructor2 ();
+       }
+
+
+       static void Test2 ()
+       {
+               Console.WriteLine ("Test 2:");
+
+               Driver.mre1.Reset ();
+               Driver.mre2.Reset ();
+
+               Thread thread = new Thread (() => {
+                       try {
+                               StaticConstructor2.Init ();
+                       } catch (TypeInitializationException e) {
+                               Console.WriteLine (e);
+
+                               if (!(e.InnerException is StaticConstructor2Exception))
+                                       throw;
+                       }
+               });
+
+               thread.Start ();
+
+               Driver.mre1.WaitOne ();
+
+               // A InvalidOperationException should be thrown while in
+               // the StaticConstructor2.cctor. The exception should
+               // be wrapped in a TypeInitializationException.
+
+               if (Driver.mre2.WaitOne (500)) {
+                       /* We shouldn't reach Driver.mre.Set () in StaticConstructor2.cctor */
+                       Environment.Exit (1);
+               }
+
+               thread.Join ();
+
+               //is StaticConstructor2 viable?
+               try {
+                       IsStaticConstructor2Viable ();
+                       Console.WriteLine ("StaticConstructor2 is viable");
+                       /* A regular exception escaping the .cctor makes the type not usable */
+                       Environment.Exit (1);
+               } catch (TypeInitializationException e) {
+                       Console.WriteLine ("StaticConstructor2 not viable");
+               }
+
+       }
+
+       class StaticConstructor3
+       {
+               static StaticConstructor3 ()
+               {
+                       Console.WriteLine ("StaticConstructor3.StaticConstructor3 (1)");
+                       Driver.mre1.Set ();
+                       Thread.CurrentThread.Abort ();
+                       /* Unreachable */
+                       Driver.mre2.Set ();
+                       Console.WriteLine ("StaticConstructor3.StaticConstructor3 (2)");
+                       Environment.Exit (1);
+               }
+
+               public static void Init ()
+               {
+                       Console.WriteLine ("StaticConstructor3.Init");
+               }
+       }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       static void IsStaticConstructor3Viable () {
+               new StaticConstructor3 ();
+       }
+
+       static void Test3 ()
+       {
+               Console.WriteLine ("Test 3:");
+
+               Driver.mre1.Reset ();
+               Driver.mre2.Reset ();
+
+               Thread thread = new Thread (() => {
+                       try {
+                               StaticConstructor3.Init ();
+                               Console.WriteLine ("cctor3 didn't throw?!?!");
+                               /* StaticConstructor3 self aborted */
+                               Environment.Exit (1);
+                       } catch (ThreadAbortException e) {
+                               Console.WriteLine ("TEST 3: aborted {0}", e);
+                       }
+               });
+
+               thread.Start ();
+
+               Driver.mre1.WaitOne ();
+
+               // A InvalidOperationException should be thrown while in
+               // the StaticConstructor2.cctor. The exception should
+               // be wrapped in a TypeInitializationException.
+
+               thread.Join ();
+
+               //is StaticConstructor2 viable?
+               try {
+                       IsStaticConstructor3Viable ();
+                       Console.WriteLine ("StaticConstructor3 is viable");
+                       /* A regular exception escaping the .cctor makes the type not usable */
+                       Environment.Exit (1);
+               } catch (TypeInitializationException e) {
+                       Console.WriteLine ("StaticConstructor3 not viable");
+               }
+       }
+
+
+
+
+
+       class StaticConstructor4
+       {
+               internal static bool gotToEnd, caughtException;
+
+               static StaticConstructor4 ()
+               {
+                       try {
+                               Console.WriteLine ("StaticConstructor4.StaticConstructor4 (1)");
+                               Driver.mre1.Set ();
+                               var sw = Stopwatch.StartNew ();
+                               Thread.Sleep (1000);
+                               sw.Stop ();
+                               typeof (string).GetMethods ();
+                               //XXX we assume that if we slept less than 900ms we got aborted
+                               if (sw.ElapsedMilliseconds < 900)
+                                       throw new Exception ("Bad abort broke our sleep");
+                               Console.WriteLine ("StaticConstructor4.StaticConstructor4 (2) waited {0}", sw.ElapsedMilliseconds);
+                               gotToEnd = true;
+                       } catch (Exception e) {
+                               caughtException = true;
+                               throw;
+                       }       
+               }
+
+               public static void Init ()
+               {
+                       Console.WriteLine ("StaticConstructor4.Init");
+               }
+       }
+
+       static bool got_to_the_end_of_the_finally = false;
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       static void IsStaticConstructor4Viable () {
+               new StaticConstructor4 ();
+               Console.WriteLine ("IsStaticConstructor4Viable: Did it get to the end? {0} Did it catch an exception {1} and end of the finally block {2}", StaticConstructor4.gotToEnd, StaticConstructor4.caughtException, got_to_the_end_of_the_finally);
+               if (!StaticConstructor4.gotToEnd) /* the TAE must not land during a .cctor */
+                       Environment.Exit (1);
+               if (StaticConstructor4.caughtException)
+                       Environment.Exit (1);
+       }
+
+       static void Test4 ()
+       {
+               Console.WriteLine ("Test 4:");
+
+               Driver.mre1.Reset ();
+               Driver.mre2.Reset ();
+
+               Thread thread = new Thread (() => {
+                       try {
+
+                               try {
+                               } finally {
+                                       StaticConstructor4.Init ();
+                                       Console.WriteLine ("Test 4: After the cctor");
+                                       got_to_the_end_of_the_finally = true;
+                               }
+                       } catch (Exception e) {
+                               Console.WriteLine ("StaticConstructor4::init caught exception {0}", e);
+                               if (!(e is ThreadAbortException))
+                                       throw;
+                               if (!got_to_the_end_of_the_finally)
+                                       throw new Exception ("Test 4: did not get to the end of the cctor");
+                       }
+               });
+
+               thread.Start ();
+
+               Driver.mre1.WaitOne ();
+
+               // The ThreadAbortException should land while in
+               // the StaticConstructor4.cctor. The exception should
+               // be queued, and be rethrown when exiting the cctor.
+               thread.Abort ();
+
+               thread.Join ();
+
+               if (!got_to_the_end_of_the_finally) { 
+                       Console.WriteLine ("Did not get to the end of test 4 cctor");
+                       Environment.Exit (1);
+               }
+
+               //is StaticConstructor4viable?
+               try {
+                       IsStaticConstructor4Viable ();
+                       Console.WriteLine ("StaticConstructor4 is viable"); /* a TAE doesn't make a type unusable */
+               } catch (TypeInitializationException  e) {
+                       Console.WriteLine ("StaticConstructor4 not viable");
+                       Environment.Exit (1);
+               }
+       }
+
+
+
+       public static int Main ()
+       {
+               Test1 ();
+               Test2 ();
+               Test3 ();
+               Test4 ();
+               Console.WriteLine ("done, all things good");
+               return 0;
+       }
+}
\ No newline at end of file
index 8f1cef273f40075165310ad858c344b9fb71324f..62529ecc557579f80dd442a8da3fcac7ca42ca1e 100644 (file)
@@ -7220,3 +7220,12 @@ mono_return_double_array4 (double_array4 sa4, int addend) {
        return sa4;
 }
 
+typedef struct {
+       int array [3];
+} FixedArrayStruct;
+
+LIBTEST_API int STDCALL
+mono_test_marshal_fixed_array (FixedArrayStruct s)
+{
+       return s.array [0] + s.array [1] + s.array [2];
+}
index 9b80f969d65eeebb526c3f90e46a2a32f90d6f95..e170ba441ab44b5f9b32da5c914faac2a80d437d 100644 (file)
@@ -9,7 +9,7 @@ using System.Runtime.InteropServices;
 using System.Runtime.CompilerServices;
 using System.Reflection.Emit;
 
-public class Tests {
+public unsafe class Tests {
 
        public int int_field;
 
@@ -1904,5 +1904,23 @@ public class Tests {
                else
                        return 0;
        }
+
+    [StructLayout(LayoutKind.Explicit, Size = 12)]
+       public struct FixedArrayStruct {
+        [FieldOffset(0)]
+        public fixed int array[3];
+       }
+
+       [DllImport ("libtest", EntryPoint="mono_test_marshal_fixed_array")]
+       public static extern int mono_test_marshal_fixed_array (FixedArrayStruct s);
+
+       public static unsafe int test_6_fixed_array_struct () {
+               var s = new FixedArrayStruct ();
+               s.array [0] = 1;
+               s.array [1] = 2;
+               s.array [2] = 3;
+
+               return mono_test_marshal_fixed_array (s);
+       }
 }
 
diff --git a/mono/tests/reference-loader.cs b/mono/tests/reference-loader.cs
new file mode 100644 (file)
index 0000000..9cdda7a
--- /dev/null
@@ -0,0 +1,111 @@
+//
+// reference-loader.cs:
+//
+//  Test for reference assembly loading
+
+using System;
+using System.IO;
+using System.Reflection;
+
+public class Tests {
+       public static int Main (string[] args)
+       {
+               return TestDriver.RunTests (typeof (Tests), args);
+       }
+
+       public static int test_0_loadFrom_reference ()
+       {
+               // Check that loading a reference assembly by filename for execution is an error
+               try {
+                       var a = Assembly.LoadFrom ("./TestingReferenceAssembly.dll");
+               } catch (BadImageFormatException exn) {
+                       // Console.Error.WriteLine ("exn was {0}", exn);
+                       return 0;
+               }
+               return 1;
+       }
+
+       public static int test_0_load_reference ()
+       {
+               // Check that loading a reference assembly for execution is an error
+               try {
+                       var an = new AssemblyName ("TestingReferenceAssembly");
+                       var a = Assembly.Load (an);
+               } catch (BadImageFormatException exn) {
+                       //Console.Error.WriteLine ("exn was {0}", exn);
+                       return 0;
+               } catch (FileNotFoundException exn) {
+                       Console.Error.WriteLine ("incorrect exn was {0}", exn);
+                       return 2;
+               }
+               return 1;
+       }
+
+       public static int test_0_reflection_load_reference ()
+       {
+               // Check that reflection-only loading a reference assembly is okay
+               var an = new AssemblyName ("TestingReferenceAssembly");
+               var a = Assembly.ReflectionOnlyLoad (an.FullName);
+               var t = a.GetType ("X");
+               var f = t.GetField ("Y");
+               if (f.FieldType.Equals (typeof (Int32)))
+                       return 0;
+               return 1;
+       }
+
+       public static int test_0_load_reference_asm_via_reference ()
+       {
+               // Check that loading an assembly that references a reference assembly doesn't succeed.
+               var an = new AssemblyName ("TestingReferenceReferenceAssembly");
+               try {
+                       var a = Assembly.Load (an);
+                       var t = a.GetType ("Z");
+               } catch (FileNotFoundException){
+                       return 0;
+               }
+               return 1;
+       }
+
+       public static int test_0_reflection_load_reference_asm_via_reference ()
+       {
+               // Check that reflection-only loading an assembly that
+               // references a reference assembly is okay.
+               var an = new AssemblyName ("TestingReferenceReferenceAssembly");
+               var a = Assembly.ReflectionOnlyLoad (an.FullName);
+               var t = a.GetType ("Z");
+               var f = t.GetField ("Y");
+               if (f.FieldType.Equals (typeof (Int32)))
+                       return 0;
+               return 1;
+       }
+
+
+       public static int test_0_load_reference_bytes ()
+       {
+               // Check that loading a reference assembly from a byte array for execution is an error
+               byte[] bs = File.ReadAllBytes ("./TestingReferenceAssembly.dll");
+               try {
+                       var a = Assembly.Load (bs);
+               } catch (BadImageFormatException) {
+                       return 0;
+               } catch (FileNotFoundException exn) {
+                       Console.Error.WriteLine ("incorrect exn was {0}", exn);
+                       return 2;
+               }
+               return 1;
+       }
+
+       public static int test_0_reflection_load_reference_bytes ()
+       {
+               // Check that loading a reference assembly from a byte
+               // array for reflection only is okay.
+               byte[] bs = File.ReadAllBytes ("./TestingReferenceAssembly.dll");
+               var a = Assembly.ReflectionOnlyLoad (bs);
+               var t = a.GetType ("X");
+               var f = t.GetField ("Y");
+               if (f.FieldType.Equals (typeof (Int32)))
+                       return 0;
+               return 1;
+       }
+
+}
index 68fc0a5d0603301897fe4cbad95de05495156d25..7c8dbc087311677c159a0f3b86b57f8e6d62ef6f 100644 (file)
@@ -111,13 +111,29 @@ class Driver {
                var heads = new Bridge [FAN_OUT];
                for (int i = 0; i < FAN_OUT; ++i)
                        heads [i] = new Bridge ();
-               var multiplexer = new Bridge [FAN_OUT];
-               for (int i = 0; i < FAN_OUT; ++i)
-               {
-                       heads [i].Links.Add (multiplexer);
-                       multiplexer [i] = new Bridge ();
+
+               // We make five identical multiplexers to verify Tarjan-bridge can merge them together correctly.
+               var MULTIPLEXER_COUNT = 5;
+               Bridge[] multiplexer0 = null;
+               for(int m = 0; m < MULTIPLEXER_COUNT; m++) {
+                       var multiplexer = new Bridge [FAN_OUT];
+                       if (m == 0) {
+                               multiplexer0 = multiplexer;
+                               for (int i = 0; i < FAN_OUT; ++i)
+                               {
+                                       heads [i].Links.Add (multiplexer);
+                                       multiplexer [i] = new Bridge ();
+                               }
+                       } else {
+                               for (int i = 0; i < FAN_OUT; ++i)
+                               {
+                                       heads [i].Links.Add (multiplexer);
+                                       multiplexer [i] = multiplexer0 [i];
+                               }
+                       }
                }
-               Console.WriteLine ("-double fan done-");
+
+               Console.WriteLine ("-double fan x5 done-");
        }
 
        /*
index 32d859c50d56cee18c92a9518db37a9c762a0597..abb24d9825f3ff143e20fa0cf73009455c72f1d8 100644 (file)
@@ -11,6 +11,7 @@
 #include "utils/mono-threads.h"
 #include "utils/mono-conc-hashtable.h"
 #include "utils/checked-build.h"
+#include "utils/w32handle.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -335,6 +336,9 @@ main (void)
        memset (&ticallbacks, 0, sizeof (ticallbacks));
        ticallbacks.thread_state_init = thread_state_init;
        mono_threads_runtime_init (&ticallbacks);
+#ifndef HOST_WIN32
+       mono_w32handle_init ();
+#endif
 
        mono_thread_info_attach ((gpointer)&cb);
 
index 3841581e0bb02fd61fe9f407dbcbef8891a0cea9..a5e01ebe09ec6e5f913e1ad936c822596d39ecde 100644 (file)
@@ -74,11 +74,11 @@ worker (void *arg)
                        break;
                case STATE_OUT:
                        if (InterlockedCompareExchange (&nodes [i].state, STATE_BUSY, STATE_OUT) == STATE_OUT) {
-                               result = mono_lls_find (&lls, hp, i, HAZARD_FREE_SAFE_CTX);
+                               result = mono_lls_find (&lls, hp, i);
                                assert (!result);
                                mono_hazard_pointer_clear_all (hp, -1);
 
-                               result = mono_lls_insert (&lls, hp, &nodes [i].node, HAZARD_FREE_SAFE_CTX);
+                               result = mono_lls_insert (&lls, hp, &nodes [i].node);
                                mono_hazard_pointer_clear_all (hp, -1);
 
                                assert (nodes [i].state == STATE_BUSY);
@@ -89,12 +89,12 @@ worker (void *arg)
                        break;
                case STATE_IN:
                        if (InterlockedCompareExchange (&nodes [i].state, STATE_BUSY, STATE_IN) == STATE_IN) {
-                               result = mono_lls_find (&lls, hp, i, HAZARD_FREE_SAFE_CTX);
+                               result = mono_lls_find (&lls, hp, i);
                                assert (result);
                                assert (mono_hazard_pointer_get_val (hp, 1) == &nodes [i].node);
                                mono_hazard_pointer_clear_all (hp, -1);
 
-                               result = mono_lls_remove (&lls, hp, &nodes [i].node, HAZARD_FREE_SAFE_CTX);
+                               result = mono_lls_remove (&lls, hp, &nodes [i].node);
                                mono_hazard_pointer_clear_all (hp, -1);
 
                                ++thread_data->num_removes;
@@ -126,7 +126,7 @@ main (int argc, char *argv [])
 
        mono_threads_init (&thread_callbacks, 0);
 
-       mono_lls_init (&lls, free_node, HAZARD_FREE_NO_LOCK);
+       mono_lls_init (&lls, free_node);
 
        for (i = 0; i < N; ++i) {
                nodes [i].node.key = i;
index 2e873cde79844c8793f096b5913a5cc854e28103..d67b9ff1fed2bb89a6a5697356203fd73b123b95 100644 (file)
@@ -130,6 +130,7 @@ monoutils_sources = \
        atomic.c        \
        mono-hwcap.h    \
        mono-hwcap.c    \
+       mono-hwcap-vars.h       \
        bsearch.h       \
        bsearch.c       \
        mono-signal-handler.h   \
@@ -182,48 +183,56 @@ arch_sources += mach-support-unknown.c
 
 endif
 
+if !CROSS_COMPILE
+
 if X86
-arch_sources += mono-hwcap-x86.c mono-hwcap-x86.h
+arch_sources += mono-hwcap-x86.c
 endif
 
 if AMD64
-arch_sources += mono-hwcap-x86.c mono-hwcap-x86.h
+arch_sources += mono-hwcap-x86.c
 endif
 
 if ARM
-arch_sources += mono-hwcap-arm.c mono-hwcap-arm.h
+arch_sources += mono-hwcap-arm.c
 endif
 
 if ARM64
-arch_sources += mono-hwcap-arm64.c mono-hwcap-arm64.h
+arch_sources += mono-hwcap-arm64.c
 endif
 
 if MIPS
-arch_sources += mono-hwcap-mips.c mono-hwcap-mips.h
+arch_sources += mono-hwcap-mips.c
 endif
 
 if POWERPC
-arch_sources += mono-hwcap-ppc.c mono-hwcap-ppc.h
+arch_sources += mono-hwcap-ppc.c
 endif
 
 if POWERPC64
-arch_sources += mono-hwcap-ppc.c mono-hwcap-ppc.h
+arch_sources += mono-hwcap-ppc.c
 endif
 
 if SPARC
-arch_sources += mono-hwcap-sparc.c mono-hwcap-sparc.h
+arch_sources += mono-hwcap-sparc.c
 endif
 
 if SPARC64
-arch_sources += mono-hwcap-sparc.c mono-hwcap-sparc.h
+arch_sources += mono-hwcap-sparc.c
 endif
 
 if IA64
-arch_sources += mono-hwcap-ia64.c mono-hwcap-ia64.h
+arch_sources += mono-hwcap-ia64.c
 endif
 
 if S390X
-arch_sources += mono-hwcap-s390x.c mono-hwcap-s390x.h
+arch_sources += mono-hwcap-s390x.c
+endif
+
+else
+
+arch_sources += mono-hwcap-cross.c
+
 endif
 
 libmonoutils_la_SOURCES = $(monoutils_sources) $(arch_sources)
index 4f5f010afd31bd61551347f754fe9f31639b0bae..dca6170a1a1e72cfe2f03cc77a5ce9a2895e1d6d 100755 (executable)
@@ -14,6 +14,7 @@
 
 #include "config.h"
 #include <glib.h>
+#include <mono/utils/mono-membar.h>
 
 /*
 The current Nexus 7 arm-v7a fails with:
@@ -29,7 +30,6 @@ Apple targets have historically being problematic, xcode 4.6 would miscompile th
 #define WIN32_LEAN_AND_MEAN
 #endif
 #include <windows.h>
-#include <mono/utils/mono-membar.h>
 
 /* mingw is missing InterlockedCompareExchange64 () from winbase.h */
 #if HAVE_DECL_INTERLOCKEDCOMPAREEXCHANGE64==0
@@ -180,30 +180,63 @@ static inline void InterlockedWrite16(volatile gint16 *dst, gint16 val)
 /* Prefer GCC atomic ops if the target supports it (see configure.ac). */
 #elif defined(USE_GCC_ATOMIC_OPS)
 
+/*
+ * As of this comment (August 2016), all current Clang versions get atomic
+ * intrinsics on ARM64 wrong. All GCC versions prior to 5.3.0 do, too. The bug
+ * is the same: The compiler developers thought that the acq + rel barriers
+ * that ARM64 load/store instructions can impose are sufficient to provide
+ * sequential consistency semantics. This is not the case:
+ *
+ *     http://lists.infradead.org/pipermail/linux-arm-kernel/2014-February/229588.html
+ *
+ * We work around this bug by inserting full barriers around each atomic
+ * intrinsic if we detect that we're built with a buggy compiler.
+ */
+
+#if defined (HOST_ARM64) && (defined (__clang__) || MONO_GNUC_VERSION < 50300)
+#define WRAP_ATOMIC_INTRINSIC(INTRIN) \
+       ({ \
+               mono_memory_barrier (); \
+               __typeof__ (INTRIN) atomic_ret__ = (INTRIN); \
+               mono_memory_barrier (); \
+               atomic_ret__; \
+       })
+
+#define gcc_sync_val_compare_and_swap(a, b, c) WRAP_ATOMIC_INTRINSIC (__sync_val_compare_and_swap (a, b, c))
+#define gcc_sync_add_and_fetch(a, b) WRAP_ATOMIC_INTRINSIC (__sync_add_and_fetch (a, b))
+#define gcc_sync_sub_and_fetch(a, b) WRAP_ATOMIC_INTRINSIC (__sync_sub_and_fetch (a, b))
+#define gcc_sync_fetch_and_add(a, b) WRAP_ATOMIC_INTRINSIC (__sync_fetch_and_add (a, b))
+#else
+#define gcc_sync_val_compare_and_swap(a, b, c) __sync_val_compare_and_swap (a, b, c)
+#define gcc_sync_add_and_fetch(a, b) __sync_add_and_fetch (a, b)
+#define gcc_sync_sub_and_fetch(a, b) __sync_sub_and_fetch (a, b)
+#define gcc_sync_fetch_and_add(a, b) __sync_fetch_and_add (a, b)
+#endif
+
 static inline gint32 InterlockedCompareExchange(volatile gint32 *dest,
                                                gint32 exch, gint32 comp)
 {
-       return __sync_val_compare_and_swap (dest, comp, exch);
+       return gcc_sync_val_compare_and_swap (dest, comp, exch);
 }
 
 static inline gpointer InterlockedCompareExchangePointer(volatile gpointer *dest, gpointer exch, gpointer comp)
 {
-       return __sync_val_compare_and_swap (dest, comp, exch);
+       return gcc_sync_val_compare_and_swap (dest, comp, exch);
 }
 
 static inline gint32 InterlockedAdd(volatile gint32 *dest, gint32 add)
 {
-       return __sync_add_and_fetch (dest, add);
+       return gcc_sync_add_and_fetch (dest, add);
 }
 
 static inline gint32 InterlockedIncrement(volatile gint32 *val)
 {
-       return __sync_add_and_fetch (val, 1);
+       return gcc_sync_add_and_fetch (val, 1);
 }
 
 static inline gint32 InterlockedDecrement(volatile gint32 *val)
 {
-       return __sync_sub_and_fetch (val, 1);
+       return gcc_sync_sub_and_fetch (val, 1);
 }
 
 static inline gint32 InterlockedExchange(volatile gint32 *val, gint32 new_val)
@@ -211,7 +244,7 @@ static inline gint32 InterlockedExchange(volatile gint32 *val, gint32 new_val)
        gint32 old_val;
        do {
                old_val = *val;
-       } while (__sync_val_compare_and_swap (val, old_val, new_val) != old_val);
+       } while (gcc_sync_val_compare_and_swap (val, old_val, new_val) != old_val);
        return old_val;
 }
 
@@ -221,30 +254,30 @@ static inline gpointer InterlockedExchangePointer(volatile gpointer *val,
        gpointer old_val;
        do {
                old_val = *val;
-       } while (__sync_val_compare_and_swap (val, old_val, new_val) != old_val);
+       } while (gcc_sync_val_compare_and_swap (val, old_val, new_val) != old_val);
        return old_val;
 }
 
 static inline gint32 InterlockedExchangeAdd(volatile gint32 *val, gint32 add)
 {
-       return __sync_fetch_and_add (val, add);
+       return gcc_sync_fetch_and_add (val, add);
 }
 
 static inline gint8 InterlockedRead8(volatile gint8 *src)
 {
        /* Kind of a hack, but GCC doesn't give us anything better, and it's
         * certainly not as bad as using a CAS loop. */
-       return __sync_fetch_and_add (src, 0);
+       return gcc_sync_fetch_and_add (src, 0);
 }
 
 static inline gint16 InterlockedRead16(volatile gint16 *src)
 {
-       return __sync_fetch_and_add (src, 0);
+       return gcc_sync_fetch_and_add (src, 0);
 }
 
 static inline gint32 InterlockedRead(volatile gint32 *src)
 {
-       return __sync_fetch_and_add (src, 0);
+       return gcc_sync_fetch_and_add (src, 0);
 }
 
 static inline void InterlockedWrite8(volatile gint8 *dst, gint8 val)
@@ -253,7 +286,7 @@ static inline void InterlockedWrite8(volatile gint8 *dst, gint8 val)
        gint8 old_val;
        do {
                old_val = *dst;
-       } while (__sync_val_compare_and_swap (dst, old_val, val) != old_val);
+       } while (gcc_sync_val_compare_and_swap (dst, old_val, val) != old_val);
 }
 
 static inline void InterlockedWrite16(volatile gint16 *dst, gint16 val)
@@ -261,7 +294,7 @@ static inline void InterlockedWrite16(volatile gint16 *dst, gint16 val)
        gint16 old_val;
        do {
                old_val = *dst;
-       } while (__sync_val_compare_and_swap (dst, old_val, val) != old_val);
+       } while (gcc_sync_val_compare_and_swap (dst, old_val, val) != old_val);
 }
 
 static inline void InterlockedWrite(volatile gint32 *dst, gint32 val)
@@ -270,7 +303,7 @@ static inline void InterlockedWrite(volatile gint32 *dst, gint32 val)
        gint32 old_val;
        do {
                old_val = *dst;
-       } while (__sync_val_compare_and_swap (dst, old_val, val) != old_val);
+       } while (gcc_sync_val_compare_and_swap (dst, old_val, val) != old_val);
 }
 
 #if defined (TARGET_OSX) || defined (__arm__) || (defined (__mips__) && !defined (__mips64)) || (defined (__powerpc__) && !defined (__powerpc64__)) || (defined (__sparc__) && !defined (__arch64__))
@@ -281,33 +314,33 @@ static inline void InterlockedWrite(volatile gint32 *dst, gint32 val)
 
 static inline gint64 InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp)
 {
-       return __sync_val_compare_and_swap (dest, comp, exch);
+       return gcc_sync_val_compare_and_swap (dest, comp, exch);
 }
 
 static inline gint64 InterlockedAdd64(volatile gint64 *dest, gint64 add)
 {
-       return __sync_add_and_fetch (dest, add);
+       return gcc_sync_add_and_fetch (dest, add);
 }
 
 static inline gint64 InterlockedIncrement64(volatile gint64 *val)
 {
-       return __sync_add_and_fetch (val, 1);
+       return gcc_sync_add_and_fetch (val, 1);
 }
 
 static inline gint64 InterlockedDecrement64(volatile gint64 *val)
 {
-       return __sync_sub_and_fetch (val, 1);
+       return gcc_sync_sub_and_fetch (val, 1);
 }
 
 static inline gint64 InterlockedExchangeAdd64(volatile gint64 *val, gint64 add)
 {
-       return __sync_fetch_and_add (val, add);
+       return gcc_sync_fetch_and_add (val, add);
 }
 
 static inline gint64 InterlockedRead64(volatile gint64 *src)
 {
        /* Kind of a hack, but GCC doesn't give us anything better. */
-       return __sync_fetch_and_add (src, 0);
+       return gcc_sync_fetch_and_add (src, 0);
 }
 
 #else
@@ -393,122 +426,6 @@ static inline void InterlockedWrite64(volatile gint64 *dst, gint64 val)
        InterlockedExchange64 (dst, val);
 }
 
-#elif defined(__ia64__)
-
-#ifdef __INTEL_COMPILER
-#include <ia64intrin.h>
-#endif
-
-static inline gint32 InterlockedCompareExchange(gint32 volatile *dest,
-                                               gint32 exch, gint32 comp)
-{
-       gint32 old;
-       guint64 real_comp;
-
-#ifdef __INTEL_COMPILER
-       old = _InterlockedCompareExchange (dest, exch, comp);
-#else
-       /* cmpxchg4 zero extends the value read from memory */
-       real_comp = (guint64)(guint32)comp;
-       asm volatile ("mov ar.ccv = %2 ;;\n\t"
-                                 "cmpxchg4.acq %0 = [%1], %3, ar.ccv\n\t"
-                                 : "=r" (old) : "r" (dest), "r" (real_comp), "r" (exch));
-#endif
-
-       return(old);
-}
-
-static inline gpointer InterlockedCompareExchangePointer(gpointer volatile *dest,
-                                               gpointer exch, gpointer comp)
-{
-       gpointer old;
-
-#ifdef __INTEL_COMPILER
-       old = _InterlockedCompareExchangePointer (dest, exch, comp);
-#else
-       asm volatile ("mov ar.ccv = %2 ;;\n\t"
-                                 "cmpxchg8.acq %0 = [%1], %3, ar.ccv\n\t"
-                                 : "=r" (old) : "r" (dest), "r" (comp), "r" (exch));
-#endif
-
-       return(old);
-}
-
-static inline gint32 InterlockedIncrement(gint32 volatile *val)
-{
-#ifdef __INTEL_COMPILER
-       return _InterlockedIncrement (val);
-#else
-       gint32 old;
-
-       do {
-               old = *val;
-       } while (InterlockedCompareExchange (val, old + 1, old) != old);
-
-       return old + 1;
-#endif
-}
-
-static inline gint32 InterlockedDecrement(gint32 volatile *val)
-{
-#ifdef __INTEL_COMPILER
-       return _InterlockedDecrement (val);
-#else
-       gint32 old;
-
-       do {
-               old = *val;
-       } while (InterlockedCompareExchange (val, old - 1, old) != old);
-
-       return old - 1;
-#endif
-}
-
-static inline gint32 InterlockedExchange(gint32 volatile *dest, gint32 new_val)
-{
-#ifdef __INTEL_COMPILER
-       return _InterlockedExchange (dest, new_val);
-#else
-       gint32 res;
-
-       do {
-               res = *dest;
-       } while (InterlockedCompareExchange (dest, new_val, res) != res);
-
-       return res;
-#endif
-}
-
-static inline gpointer InterlockedExchangePointer(gpointer volatile *dest, gpointer new_val)
-{
-#ifdef __INTEL_COMPILER
-       return (gpointer)_InterlockedExchange64 ((gint64*)dest, (gint64)new_val);
-#else
-       gpointer res;
-
-       do {
-               res = *dest;
-       } while (InterlockedCompareExchangePointer (dest, new_val, res) != res);
-
-       return res;
-#endif
-}
-
-static inline gint32 InterlockedExchangeAdd(gint32 volatile *val, gint32 add)
-{
-       gint32 old;
-
-#ifdef __INTEL_COMPILER
-       old = _InterlockedExchangeAdd (val, add);
-#else
-       do {
-               old = *val;
-       } while (InterlockedCompareExchange (val, old + add, old) != old);
-
-       return old;
-#endif
-}
-
 #else
 
 #define WAPI_NO_ATOMIC_ASM
index efe6b649b3039450cbdc176f0373cd55754a69be..cddcd1c63b037edc4192e7e2fb0c969372f350bc 100644 (file)
@@ -29,7 +29,6 @@
 typedef struct {
        gpointer p;
        MonoHazardousFreeFunc free_func;
-       HazardFreeLocking locking;
 } DelayedFreeItem;
 
 /* The hazard table */
@@ -191,7 +190,7 @@ mono_hazard_pointer_get (void)
    mono_jit_info_table_add(), which doesn't have to care about hazards
    because it holds the respective domain lock. */
 gpointer
-get_hazardous_pointer (gpointer volatile *pp, MonoThreadHazardPointers *hp, int hazard_index)
+mono_get_hazardous_pointer (gpointer volatile *pp, MonoThreadHazardPointers *hp, int hazard_index)
 {
        gpointer p;
 
@@ -287,26 +286,6 @@ mono_hazard_pointer_restore_for_signal_handler (int small_id)
        overflow_busy [small_id] = 0;
 }
 
-static gboolean
-try_free_delayed_free_item (HazardFreeContext context)
-{
-       DelayedFreeItem item;
-       gboolean popped = mono_lock_free_array_queue_pop (&delayed_free_queue, &item);
-
-       if (!popped)
-               return FALSE;
-
-       if ((context == HAZARD_FREE_ASYNC_CTX && item.locking == HAZARD_FREE_MAY_LOCK) ||
-           (is_pointer_hazardous (item.p))) {
-               mono_lock_free_array_queue_push (&delayed_free_queue, &item);
-               return FALSE;
-       }
-
-       item.free_func (item.p);
-
-       return TRUE;
-}
-
 /**
  * mono_thread_hazardous_try_free:
  * @p: the pointer to free
@@ -348,7 +327,7 @@ mono_thread_hazardous_try_free (gpointer p, MonoHazardousFreeFunc free_func)
 void
 mono_thread_hazardous_queue_free (gpointer p, MonoHazardousFreeFunc free_func)
 {
-       DelayedFreeItem item = { p, free_func, HAZARD_FREE_MAY_LOCK };
+       DelayedFreeItem item = { p, free_func };
 
        InterlockedIncrement (&hazardous_pointer_count);
 
@@ -366,19 +345,48 @@ mono_hazard_pointer_install_free_queue_size_callback (MonoHazardFreeQueueSizeCal
        queue_size_cb = cb;
 }
 
+static void
+try_free_delayed_free_items (guint32 limit)
+{
+       GArray *hazardous = NULL;
+       DelayedFreeItem item;
+       guint32 freed = 0;
+
+       // Free all the items we can and re-add the ones we can't to the queue.
+       while (mono_lock_free_array_queue_pop (&delayed_free_queue, &item)) {
+               if (is_pointer_hazardous (item.p)) {
+                       if (!hazardous)
+                               hazardous = g_array_sized_new (FALSE, FALSE, sizeof (DelayedFreeItem), delayed_free_queue.num_used_entries);
+
+                       g_array_append_val (hazardous, item);
+                       continue;
+               }
+
+               item.free_func (item.p);
+               freed++;
+
+               if (limit && freed == limit)
+                       break;
+       }
+
+       if (hazardous) {
+               for (gint i = 0; i < hazardous->len; i++)
+                       mono_lock_free_array_queue_push (&delayed_free_queue, &g_array_index (hazardous, DelayedFreeItem, i));
+
+               g_array_free (hazardous, TRUE);
+       }
+}
+
 void
 mono_thread_hazardous_try_free_all (void)
 {
-       while (try_free_delayed_free_item (HAZARD_FREE_SAFE_CTX))
-               ;
+       try_free_delayed_free_items (0);
 }
 
 void
 mono_thread_hazardous_try_free_some (void)
 {
-       int i;
-       for (i = 0; i < 10; ++i)
-               try_free_delayed_free_item (HAZARD_FREE_SAFE_CTX);
+       try_free_delayed_free_items (10);
 }
 
 void
index 0102c103f7629785b1eb8c231a88f86269dbc56c..558c0ad0afa9d5f1a2c7896bd8a34e3c7b10cfa9 100644 (file)
@@ -20,23 +20,13 @@ typedef struct {
 
 typedef void (*MonoHazardousFreeFunc) (gpointer p);
 
-typedef enum {
-       HAZARD_FREE_MAY_LOCK,
-       HAZARD_FREE_NO_LOCK,
-} HazardFreeLocking;
-
-typedef enum {
-       HAZARD_FREE_SAFE_CTX,
-       HAZARD_FREE_ASYNC_CTX,
-} HazardFreeContext;
-
 MONO_API gboolean mono_thread_hazardous_try_free (gpointer p, MonoHazardousFreeFunc free_func);
-void mono_thread_hazardous_queue_free (gpointer p, MonoHazardousFreeFunc free_func);
+MONO_API void mono_thread_hazardous_queue_free (gpointer p, MonoHazardousFreeFunc free_func);
 
-void mono_thread_hazardous_try_free_all (void);
+MONO_API void mono_thread_hazardous_try_free_all (void);
 void mono_thread_hazardous_try_free_some (void);
-MonoThreadHazardPointers* mono_hazard_pointer_get (void);
-gpointer get_hazardous_pointer (gpointer volatile *pp, MonoThreadHazardPointers *hp, int hazard_index);
+MONO_API MonoThreadHazardPointers* mono_hazard_pointer_get (void);
+gpointer mono_get_hazardous_pointer (gpointer volatile *pp, MonoThreadHazardPointers *hp, int hazard_index);
 
 #define mono_hazard_pointer_set(hp,i,v)        \
        do { g_assert ((i) >= 0 && (i) < HAZARD_POINTER_COUNT); \
index d103ef6aa333eeb96a920d8e62ef0af79db5ecb2..d5da3896343906457b70d185db3f4df793f9828e 100644 (file)
@@ -170,7 +170,7 @@ desc_alloc (void)
        for (;;) {
                gboolean success;
 
-               desc = (Descriptor *) get_hazardous_pointer ((gpointer * volatile)&desc_avail, hp, 1);
+               desc = (Descriptor *) mono_get_hazardous_pointer ((gpointer * volatile)&desc_avail, hp, 1);
                if (desc) {
                        Descriptor *next = desc->next;
                        success = (InterlockedCompareExchangePointer ((gpointer * volatile)&desc_avail, next, desc) == desc);
index 2e06b63f526258de4e6f2004e3fd397d8f523611..3abb84104732786d6978fed3f01d42496de8585d 100644 (file)
@@ -133,7 +133,7 @@ mono_lock_free_queue_enqueue (MonoLockFreeQueue *q, MonoLockFreeQueueNode *node)
        for (;;) {
                MonoLockFreeQueueNode *next;
 
-               tail = (MonoLockFreeQueueNode *) get_hazardous_pointer ((gpointer volatile*)&q->tail, hp, 0);
+               tail = (MonoLockFreeQueueNode *) mono_get_hazardous_pointer ((gpointer volatile*)&q->tail, hp, 0);
                mono_memory_read_barrier ();
                /*
                 * We never dereference next so we don't need a
@@ -243,7 +243,7 @@ mono_lock_free_queue_dequeue (MonoLockFreeQueue *q)
        for (;;) {
                MonoLockFreeQueueNode *tail, *next;
 
-               head = (MonoLockFreeQueueNode *) get_hazardous_pointer ((gpointer volatile*)&q->head, hp, 0);
+               head = (MonoLockFreeQueueNode *) mono_get_hazardous_pointer ((gpointer volatile*)&q->head, hp, 0);
                tail = (MonoLockFreeQueueNode*)q->tail;
                mono_memory_read_barrier ();
                next = head->next;
index 2b3b86e2ef2e305dd8de427b6eb4902b999283de..d03ba8051aa565a53319b35aad89cecae2b9f450 100644 (file)
@@ -303,5 +303,9 @@ typedef SSIZE_T ssize_t;
 #define MONO_COLD
 #endif
 
+#if defined (__GNUC__) && defined (__GNUC_MINOR__) && defined (__GNUC_PATCHLEVEL__)
+#define MONO_GNUC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+#endif
+
 #endif /* __UTILS_MONO_COMPILER_H__*/
 
index b5b3539d116c00eef3eba67d112ff9d521df3f9c..9b92493191ed1a08bad915c7ab7df8ecd6a5fcb5 100644 (file)
@@ -164,7 +164,7 @@ mono_conc_hashtable_lookup (MonoConcurrentHashTable *hash_table, gpointer key)
        hp = mono_hazard_pointer_get ();
 
 retry:
-       table = (conc_table *)get_hazardous_pointer ((gpointer volatile*)&hash_table->table, hp, 0);
+       table = (conc_table *)mono_get_hazardous_pointer ((gpointer volatile*)&hash_table->table, hp, 0);
        table_mask = table->table_size - 1;
        kvs = table->kvs;
        i = hash & table_mask;
index 758c3dc6fc2651487fc8cc87fcd97714f1882d13..e51387776b93ed25d0c69b83d1abdd1d77d9b7f9 100644 (file)
@@ -19,7 +19,7 @@
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
-#include "mono/utils/mono-hwcap-arm.h"
+#include "mono/utils/mono-hwcap.h"
 
 #if defined(HAVE_SYS_AUXV_H) && !defined(PLATFORM_ANDROID)
 #include <sys/auxv.h>
 #include <stdio.h>
 #endif
 
-gboolean mono_hwcap_arm_is_v5 = FALSE;
-gboolean mono_hwcap_arm_is_v6 = FALSE;
-gboolean mono_hwcap_arm_is_v7 = FALSE;
-gboolean mono_hwcap_arm_has_vfp = FALSE;
-gboolean mono_hwcap_arm_has_vfp3 = FALSE;
-gboolean mono_hwcap_arm_has_vfp3_d16 = FALSE;
-gboolean mono_hwcap_arm_has_thumb = FALSE;
-gboolean mono_hwcap_arm_has_thumb2 = FALSE;
-
 void
 mono_hwcap_arch_init (void)
 {
@@ -202,16 +193,3 @@ mono_hwcap_arch_init (void)
        }
 #endif
 }
-
-void
-mono_hwcap_print(FILE *f)
-{
-       g_fprintf (f, "mono_hwcap_arm_is_v5 = %i\n", mono_hwcap_arm_is_v5);
-       g_fprintf (f, "mono_hwcap_arm_is_v6 = %i\n", mono_hwcap_arm_is_v6);
-       g_fprintf (f, "mono_hwcap_arm_is_v7 = %i\n", mono_hwcap_arm_is_v7);
-       g_fprintf (f, "mono_hwcap_arm_has_vfp = %i\n", mono_hwcap_arm_has_vfp);
-       g_fprintf (f, "mono_hwcap_arm_has_vfp3 = %i\n", mono_hwcap_arm_has_vfp3);
-       g_fprintf (f, "mono_hwcap_arm_has_vfp3_d16 = %i\n", mono_hwcap_arm_has_vfp3_d16);
-       g_fprintf (f, "mono_hwcap_arm_has_thumb = %i\n", mono_hwcap_arm_has_thumb);
-       g_fprintf (f, "mono_hwcap_arm_has_thumb2 = %i\n", mono_hwcap_arm_has_thumb2);
-}
diff --git a/mono/utils/mono-hwcap-arm.h b/mono/utils/mono-hwcap-arm.h
deleted file mode 100644 (file)
index 29adf7b..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef __MONO_UTILS_HWCAP_ARM_H__
-#define __MONO_UTILS_HWCAP_ARM_H__
-
-#include "mono/utils/mono-hwcap.h"
-
-extern gboolean mono_hwcap_arm_is_v5;
-extern gboolean mono_hwcap_arm_is_v6;
-extern gboolean mono_hwcap_arm_is_v7;
-extern gboolean mono_hwcap_arm_has_vfp;
-extern gboolean mono_hwcap_arm_has_vfp3;
-extern gboolean mono_hwcap_arm_has_vfp3_d16;
-extern gboolean mono_hwcap_arm_has_thumb;
-extern gboolean mono_hwcap_arm_has_thumb2;
-
-#endif /* __MONO_UTILS_HWCAP_ARM_H__ */
index 5491cff96cfd60ec93560dee66aa7343c11c5803..f541ea3df2bebc78f42295ad212f739f63f1982f 100644 (file)
@@ -1,25 +1,13 @@
 /*
- * mono-hwcap-arm64.c: ARM hardware feature detection
+ * mono-hwcap-arm64.c: ARM64 hardware feature detection
  *
  * Copyright 2013 Xamarin Inc
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
-#include "mono/utils/mono-hwcap-arm64.h"
+#include "mono/utils/mono-hwcap.h"
 
-#if defined(MONO_CROSS_COMPILE)
 void
 mono_hwcap_arch_init (void)
 {
 }
-#else
-void
-mono_hwcap_arch_init (void)
-{
-}
-#endif
-
-void
-mono_hwcap_print(FILE *f)
-{
-}
diff --git a/mono/utils/mono-hwcap-arm64.h b/mono/utils/mono-hwcap-arm64.h
deleted file mode 100644 (file)
index 2d41209..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __MONO_UTILS_HWCAP_ARM64_H__
-#define __MONO_UTILS_HWCAP_ARM64_H__
-
-#include "mono/utils/mono-hwcap.h"
-
-#endif
diff --git a/mono/utils/mono-hwcap-cross.c b/mono/utils/mono-hwcap-cross.c
new file mode 100644 (file)
index 0000000..4311a99
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * mono-hwcap-cross.c: No-op hardware feature detection
+ *
+ * Author:
+ *  Alex Rønne Petersen (alexrp@xamarin.com)
+ *
+ * Copyright 2015 Xamarin, Inc (http://www.xamarin.com)
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+
+#include "mono/utils/mono-hwcap.h"
+
+void
+mono_hwcap_arch_init (void)
+{
+}
index b5979862208a32a61fc594f5b150a183f225df6d..dd1edbd8d40dcb6d79e62325a157d585845ddd6c 100644 (file)
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
-#include "mono/utils/mono-hwcap-ia64.h"
+#include "mono/utils/mono-hwcap.h"
 
 void
 mono_hwcap_arch_init (void)
-{
-       /* Nothing needed here yet. */
-}
-
-void
-mono_hwcap_print (FILE *f)
 {
 }
diff --git a/mono/utils/mono-hwcap-ia64.h b/mono/utils/mono-hwcap-ia64.h
deleted file mode 100644 (file)
index 15b64a8..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __MONO_UTILS_HWCAP_IA64_H__
-#define __MONO_UTILS_HWCAP_IA64_H__
-
-#include "mono/utils/mono-hwcap.h"
-
-/* Nothing needed here yet. */
-
-#endif /* __MONO_UTILS_HWCAP_IA64_H__ */
index 6d809a79ac54cf488c61faf587a0f5a5d3e50196..119f930a685a4d0915736d14f4d623b4291deca8 100644 (file)
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
-#include "mono/utils/mono-hwcap-mips.h"
+#include "mono/utils/mono-hwcap.h"
 
 void
 mono_hwcap_arch_init (void)
-{
-       /* Nothing needed here yet. */
-}
-
-void
-mono_hwcap_print (FILE *f)
 {
 }
diff --git a/mono/utils/mono-hwcap-mips.h b/mono/utils/mono-hwcap-mips.h
deleted file mode 100644 (file)
index dd0622a..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __MONO_UTILS_HWCAP_MIPS_H__
-#define __MONO_UTILS_HWCAP_MIPS_H__
-
-#include "mono/utils/mono-hwcap.h"
-
-/* Nothing needed here yet. */
-
-#endif /* __MONO_UTILS_HWCAP_MIPS_H__ */
index 174cc620a202c7af27d8012b11075f09d78d93ed..af36c4d5473191c740746c83b47b726e4ddc0524 100644 (file)
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
-#include "mono/utils/mono-hwcap-ppc.h"
+#include "mono/utils/mono-hwcap.h"
 
 #if defined(__linux__) && defined(HAVE_SYS_AUXV_H)
 #include <string.h>
 #include <sys/auxv.h>
 #endif
 
-gboolean mono_hwcap_ppc_has_icache_snoop = FALSE;
-gboolean mono_hwcap_ppc_is_isa_2x = FALSE;
-gboolean mono_hwcap_ppc_is_isa_64 = FALSE;
-gboolean mono_hwcap_ppc_has_move_fpr_gpr = FALSE;
-gboolean mono_hwcap_ppc_has_multiple_ls_units = FALSE;
-
 void
 mono_hwcap_arch_init (void)
 {
@@ -66,13 +60,3 @@ mono_hwcap_arch_init (void)
        }
 #endif
 }
-
-void
-mono_hwcap_print (FILE* f)
-{
-       g_fprintf (f, "mono_hwcap_ppc_has_icache_snoop = %i\n", mono_hwcap_ppc_has_icache_snoop);
-       g_fprintf (f, "mono_hwcap_ppc_is_isa_2x = %i\n", mono_hwcap_ppc_is_isa_2x);
-       g_fprintf (f, "mono_hwcap_ppc_is_isa_64 = %i\n", mono_hwcap_ppc_is_isa_64);
-       g_fprintf (f, "mono_hwcap_ppc_has_move_fpr_gpr = %i\n", mono_hwcap_ppc_has_move_fpr_gpr);
-       g_fprintf (f, "mono_hwcap_ppc_has_multiple_ls_units = %i\n", mono_hwcap_ppc_has_multiple_ls_units);
-}
diff --git a/mono/utils/mono-hwcap-ppc.h b/mono/utils/mono-hwcap-ppc.h
deleted file mode 100644 (file)
index 0ae2578..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef __MONO_UTILS_HWCAP_PPC_H__
-#define __MONO_UTILS_HWCAP_PPC_H__
-
-#include "mono/utils/mono-hwcap.h"
-
-extern gboolean mono_hwcap_ppc_has_icache_snoop;
-extern gboolean mono_hwcap_ppc_is_isa_2x;
-extern gboolean mono_hwcap_ppc_is_isa_64;
-extern gboolean mono_hwcap_ppc_has_move_fpr_gpr;
-extern gboolean mono_hwcap_ppc_has_multiple_ls_units;
-
-#endif /* __MONO_UTILS_HWCAP_PPC_H__ */
index 19a7fba11017251a55864c39a93fa94ff5b5b2de..c578a620d925d87eca46a3709d5df296c5570654 100644 (file)
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
-#include "mono/utils/mono-hwcap-s390x.h"
+#include "mono/utils/mono-hwcap.h"
+
 #include <signal.h>
 
-facilityList_t facs;
+typedef struct {
+       uint8_t n3:1;           // 000 - N3 instructions
+       uint8_t zi:1;           // 001 - z/Arch installed
+       uint8_t za:1;           // 002 - z/Arch active
+       uint8_t date:1;         // 003 - DAT-enhancement
+       uint8_t idtes:1;        // 004 - IDTE-segment tables
+       uint8_t idter:1;        // 005 - IDTE-region tables
+       uint8_t asnlx:1;        // 006 - ASN-LX reuse
+       uint8_t stfle:1;        // 007 - STFLE
+       uint8_t edat1:1;        // 008 - EDAT 1
+       uint8_t srs:1;          // 009 - Sense-Running-Status
+       uint8_t csske:1;        // 010 - Conditional SSKE
+       uint8_t ctf:1;          // 011 - Configuration-topology
+       uint8_t ibm01:1;        // 012 - Assigned to IBM
+       uint8_t ipter:1;        // 013 - IPTE-range
+       uint8_t nqks:1;         // 014 - Nonquiescing key-setting
+       uint8_t ibm02:1;        // 015 - Assigned to IBM
+       uint8_t etf2:1;         // 016 - Extended translation 2
+       uint8_t msa:1;          // 017 - Message security assist 1
+       uint8_t ld:1;           // 018 - Long displacement
+       uint8_t ldh:1;          // 019 - Long displacement high perf
+       uint8_t mas:1;          // 020 - HFP multiply-add-subtract
+       uint8_t eif:1;          // 021 - Extended immediate
+       uint8_t etf3:1;         // 022 - Extended translation 3
+       uint8_t hux:1;          // 023 - HFP unnormalized extension
+       uint8_t etf2e:1;        // 024 - Extended translation enhanced 2
+       uint8_t stckf:1;        // 025 - Store clock fast
+       uint8_t pe:1;           // 026 - Parsing enhancement
+       uint8_t mvcos:1;        // 027 - Move with optional specs
+       uint8_t tods:1;         // 028 - TOD steering
+       uint8_t x000:1;         // 029 - Undefined
+       uint8_t etf3e:1;        // 030 - ETF3 enhancement
+       uint8_t ecput:1;        // 031 - Extract CPU time
+       uint8_t csst:1;         // 032 - Compare swap and store
+       uint8_t csst2:1;        // 033 - Compare swap and store 2
+       uint8_t gie:1;          // 034 - General instructions extension
+       uint8_t ee:1;           // 035 - Execute extensions
+       uint8_t em:1;           // 036 - Enhanced monitor
+       uint8_t fpe:1;          // 037 - Floating point extension
+       uint8_t x001:1;         // 038 - Undefined
+       uint8_t ibm03:1;        // 039 - Assigned to IBM
+       uint8_t spp:1;          // 040 - Set program parameters
+       uint8_t fpse:1;         // 041 - FP support enhancement
+       uint8_t dfp:1;          // 042 - DFP
+       uint8_t dfph:1;         // 043 - DFP high performance
+       uint8_t pfpo:1;         // 044 - PFPO instruction
+       uint8_t multi:1;        // 045 - Multiple inc load/store on CC 1
+       uint8_t ibm04:1;        // 046 - Assigned to IBM
+       uint8_t cmpsce:1;       // 047 - CMPSC enhancement
+       uint8_t dfpzc:1;        // 048 - DFP zoned conversion
+       uint8_t misc:1;         // 049 - Multiple inc load and trap
+       uint8_t ctx:1;          // 050 - Constrained transactional-execution
+       uint8_t ltlb:1;         // 051 - Local TLB clearing
+       uint8_t ia:1;           // 052 - Interlocked access
+       uint8_t lsoc2:1;        // 053 - Load/store on CC 2
+       uint8_t x002:1;         // 054 - Undefined
+       uint8_t ibm05:1;        // 055 - Assigned to IBM
+       uint8_t x003:1;         // 056 - Undefined
+       uint8_t msa5:1;         // 057 - Message security assist 5
+       uint8_t x004:1;         // 058 - Undefined
+       uint8_t x005:1;         // 059 - Undefined
+       uint8_t x006:1;         // 060 - Undefined
+       uint8_t x007:1;         // 061 - Undefined
+       uint8_t ibm06:1;        // 062 - Assigned to IBM
+       uint8_t x008:1;         // 063 - Undefined
+       uint8_t x009:1;         // 064 - Undefined
+       uint8_t ibm07:1;        // 065 - Assigned to IBM
+       uint8_t rrbm:1;         // 066 - Reset reference bits multiple
+       uint8_t cmc:1;          // 067 - CPU measurement counter
+       uint8_t cms:1;          // 068 - CPU Measurement sampling
+       uint8_t ibm08:1;        // 069 - Assigned to IBM
+       uint8_t ibm09:1;        // 070 - Assigned to IBM
+       uint8_t ibm10:1;        // 071 - Assigned to IBM
+       uint8_t ibm11:1;        // 072 - Assigned to IBM
+       uint8_t txe:1;          // 073 - Transactional execution
+       uint8_t sthy:1;         // 074 - Store hypervisor information
+       uint8_t aefsi:1;        // 075 - Access exception fetch/store indication
+       uint8_t msa3:1;         // 076 - Message security assist 3
+       uint8_t msa4:1;         // 077 - Message security assist 4
+       uint8_t edat2:1;        // 078 - Enhanced DAT 2
+       uint8_t x010:1;         // 079 - Undefined
+       uint8_t dfppc:1;        // 080 - DFP packed conversion
+       uint8_t x011:7;         // 081-87 - Undefined
+       uint8_t x012[5];        // 088-127 - Undefined
+       uint8_t ibm12:1;        // 128 - Assigned to IBM
+       uint8_t vec:1;          // 129 - Vector facility
+       uint8_t x013:6;         // 130-135 - Undefined
+       uint8_t x014:6;         // 136-141 - Undefined
+       uint8_t sccm:1;         // 142 - Store CPU counter multiple
+       uint8_t ibm13:1;        // 143 - Assigned to IBM
+       uint8_t x015[14];       // 144-256 Undefined
+} __attribute__ ((packed)) __attribute__ ((aligned(8))) facilityList_t;
 
 void
 mono_hwcap_arch_init (void)
 {
-       int lFacs = sizeof(facs) / 8;
+       facilityList_t facs;
+       int lFacs = sizeof (facs) / 8;
 
-       __asm__ ("      lgfr    0,%1\n"
-                "      .insn   s,0xb2b00000,%0\n"
-                : "=m" (facs) : "r" (lFacs) : "0", "cc");
-}
+       __asm__ __volatile__ (
+               "lgfr\t0,%1\n\t"
+               ".insn\ts,0xb2b00000,%0\n\t"
+               : "=m" (facs)
+               : "r" (lFacs)
+               : "0", "cc"
+       );
 
-void
-mono_hwcap_print (FILE *f)
-{
+       mono_hwcap_s390x_has_fpe = facs.fpe;
+       mono_hwcap_s390x_has_vec = facs.vec;
 }
diff --git a/mono/utils/mono-hwcap-s390x.h b/mono/utils/mono-hwcap-s390x.h
deleted file mode 100644 (file)
index 7a4522f..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-#ifndef __MONO_UTILS_HWCAP_S390X_H__
-#define __MONO_UTILS_HWCAP_S390X_H__
-
-#include "mono/utils/mono-hwcap.h"
-
-typedef struct __FACLIST__ {
-       uint8_t n3:1;           // 000 - N3 instructions
-       uint8_t zi:1;           // 001 - z/Arch installed
-       uint8_t za:1;           // 002 - z/Arch active
-       uint8_t date:1;         // 003 - DAT-enhancement
-       uint8_t idtes:1;        // 004 - IDTE-segment tables
-       uint8_t idter:1;        // 005 - IDTE-region tables
-       uint8_t asnlx:1;        // 006 - ASN-LX reuse
-       uint8_t stfle:1;        // 007 - STFLE
-       uint8_t edat1:1;        // 008 - EDAT 1
-       uint8_t srs:1;          // 009 - Sense-Running-Status
-       uint8_t csske:1;        // 010 - Conditional SSKE
-       uint8_t ctf:1;          // 011 - Configuration-topology
-       uint8_t ibm01:1;        // 012 - Assigned to IBM
-       uint8_t ipter:1;        // 013 - IPTE-range
-       uint8_t nqks:1;         // 014 - Nonquiescing key-setting
-       uint8_t ibm02:1;        // 015 - Assigned to IBM
-       uint8_t etf2:1;         // 016 - Extended translation 2
-       uint8_t msa:1;          // 017 - Message security assist 1
-       uint8_t ld:1;           // 018 - Long displacement
-       uint8_t ldh:1;          // 019 - Long displacement high perf
-       uint8_t mas:1;          // 020 - HFP multiply-add-subtract
-       uint8_t eif:1;          // 021 - Extended immediate
-       uint8_t etf3:1;         // 022 - Extended translation 3
-       uint8_t hux:1;          // 023 - HFP unnormalized extension
-       uint8_t etf2e:1;        // 024 - Extended translation enhanced 2
-       uint8_t stckf:1;        // 025 - Store clock fast
-       uint8_t pe:1;           // 026 - Parsing enhancement
-       uint8_t mvcos:1;        // 027 - Move with optional specs
-       uint8_t tods:1;         // 028 - TOD steering
-       uint8_t x000:1;         // 029 - Undefined
-       uint8_t etf3e:1;        // 030 - ETF3 enhancement
-       uint8_t ecput:1;        // 031 - Extract CPU time
-       uint8_t csst:1;         // 032 - Compare swap and store
-       uint8_t csst2:1;        // 033 - Compare swap and store 2
-       uint8_t gie:1;          // 034 - General instructions extension
-       uint8_t ee:1;           // 035 - Execute extensions
-       uint8_t em:1;           // 036 - Enhanced monitor
-       uint8_t fpe:1;          // 037 - Floating point extension
-       uint8_t x001:1;         // 038 - Undefined
-       uint8_t ibm03:1;        // 039 - Assigned to IBM
-       uint8_t spp:1;          // 040 - Set program parameters
-       uint8_t fpse:1;         // 041 - FP support enhancement
-       uint8_t dfp:1;          // 042 - DFP
-       uint8_t dfph:1;         // 043 - DFP high performance
-       uint8_t pfpo:1;         // 044 - PFPO instruction
-       uint8_t multi:1;        // 045 - Multiple inc load/store on CC 1
-       uint8_t ibm04:1;        // 046 - Assigned to IBM
-       uint8_t cmpsce:1;       // 047 - CMPSC enhancement
-       uint8_t dfpzc:1;        // 048 - DFP zoned conversion
-       uint8_t misc:1;         // 049 - Multiple inc load and trap
-       uint8_t ctx:1;          // 050 - Constrained transactional-execution
-       uint8_t ltlb:1;         // 051 - Local TLB clearing
-       uint8_t ia:1;           // 052 - Interlocked access
-       uint8_t lsoc2:1;        // 053 - Load/store on CC 2
-       uint8_t x002:1;         // 054 - Undefined
-       uint8_t ibm05:1;        // 055 - Assigned to IBM
-       uint8_t x003:1;         // 056 - Undefined
-       uint8_t msa5:1;         // 057 - Message security assist 5
-       uint8_t x004:1;         // 058 - Undefined
-       uint8_t x005:1;         // 059 - Undefined
-       uint8_t x006:1;         // 060 - Undefined
-       uint8_t x007:1;         // 061 - Undefined
-       uint8_t ibm06:1;        // 062 - Assigned to IBM
-       uint8_t x008:1;         // 063 - Undefined
-       uint8_t x009:1;         // 064 - Undefined
-       uint8_t ibm07:1;        // 065 - Assigned to IBM
-       uint8_t rrbm:1;         // 066 - Reset reference bits multiple
-       uint8_t cmc:1;          // 067 - CPU measurement counter
-       uint8_t cms:1;          // 068 - CPU Measurement sampling
-       uint8_t ibm08:1;        // 069 - Assigned to IBM
-       uint8_t ibm09:1;        // 070 - Assigned to IBM
-       uint8_t ibm10:1;        // 071 - Assigned to IBM
-       uint8_t ibm11:1;        // 072 - Assigned to IBM
-       uint8_t txe:1;          // 073 - Transactional execution
-       uint8_t sthy:1;         // 074 - Store hypervisor information
-       uint8_t aefsi:1;        // 075 - Access exception fetch/store indication
-       uint8_t msa3:1;         // 076 - Message security assist 3
-       uint8_t msa4:1;         // 077 - Message security assist 4
-       uint8_t edat2:1;        // 078 - Enhanced DAT 2
-       uint8_t x010:1;         // 079 - Undefined
-       uint8_t dfppc:1;        // 080 - DFP packed conversion
-       uint8_t x011:7;         // 081-87 - Undefined
-       uint8_t x012[5];        // 088-127 - Undefined
-       uint8_t ibm12:1;        // 128 - Assigned to IBM
-       uint8_t vec:1;          // 129 - Vector facility
-       uint8_t x013:6;         // 130-135 - Undefined
-       uint8_t x014:6;         // 136-141 - Undefined
-       uint8_t sccm:1;         // 142 - Store CPU counter multiple
-       uint8_t ibm13:1;        // 143 - Assigned to IBM
-       uint8_t x015[14];       // 144-256 Undefined
-} __attribute__ ((packed)) __attribute__ ((aligned(8))) facilityList_t;
-
-extern facilityList_t facs;
-
-#endif /* __MONO_UTILS_HWCAP_S390X_H__ */
index ba849873632cf0798c66c34ecddf2990056d9873..75208bdeff7bc02996f188a00eeaed769007d138 100644 (file)
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
-#include "mono/utils/mono-hwcap-sparc.h"
+#include "mono/utils/mono-hwcap.h"
 
 #include <string.h>
-
 #if !defined(__linux__)
 #include <sys/systeminfo.h>
 #else
 #include <unistd.h>
 #endif
 
-gboolean mono_hwcap_sparc_is_v9 = FALSE;
-
 void
 mono_hwcap_arch_init (void)
 {
        char buf [1024];
 
 #if !defined(__linux__)
-       if (!sysinfo (SI_ISALIST, buf, 1024))
-               g_assert_not_reached ();
+       g_assert (sysinfo (SI_ISALIST, buf, 1024));
 #else
        /* If the page size is 8192, we're on a 64-bit SPARC, which
         * in turn means a v9 or better.
@@ -51,9 +47,3 @@ mono_hwcap_arch_init (void)
 
        mono_hwcap_sparc_is_v9 = strstr (buf, "sparcv9");
 }
-
-void
-mono_hwcap_print (FILE *f)
-{
-       g_fprintf (f, "mono_hwcap_sparc_is_v9 = %i\n", mono_hwcap_sparc_is_v9);
-}
diff --git a/mono/utils/mono-hwcap-vars.h b/mono/utils/mono-hwcap-vars.h
new file mode 100644 (file)
index 0000000..620a3d4
--- /dev/null
@@ -0,0 +1,56 @@
+#include "config.h"
+
+#if defined (TARGET_ARM)
+
+MONO_HWCAP_VAR(arm_is_v5)
+MONO_HWCAP_VAR(arm_is_v6)
+MONO_HWCAP_VAR(arm_is_v7)
+MONO_HWCAP_VAR(arm_has_vfp)
+MONO_HWCAP_VAR(arm_has_vfp3)
+MONO_HWCAP_VAR(arm_has_vfp3_d16)
+MONO_HWCAP_VAR(arm_has_thumb)
+MONO_HWCAP_VAR(arm_has_thumb2)
+
+#elif defined (TARGET_ARM64)
+
+// Nothing here yet.
+
+#elif defined (TARGET_IA64)
+
+// Nothing here yet.
+
+#elif defined (TARGET_MIPS)
+
+// Nothing here yet.
+
+#elif defined (TARGET_POWERPC) || defined (TARGET_POWERPC64)
+
+MONO_HWCAP_VAR(ppc_has_icache_snoop)
+MONO_HWCAP_VAR(ppc_is_isa_2x)
+MONO_HWCAP_VAR(ppc_is_isa_64)
+MONO_HWCAP_VAR(ppc_has_move_fpr_gpr)
+MONO_HWCAP_VAR(ppc_has_multiple_ls_units)
+
+#elif defined (TARGET_S390X)
+
+MONO_HWCAP_VAR(s390x_has_fpe)
+MONO_HWCAP_VAR(s390x_has_vec)
+
+#elif defined (TARGET_SPARC) || defined (TARGET_SPARC64)
+
+MONO_HWCAP_VAR(sparc_is_v9)
+
+#elif defined (TARGET_X86) || defined (TARGET_AMD64)
+
+MONO_HWCAP_VAR(x86_is_xen)
+MONO_HWCAP_VAR(x86_has_cmov)
+MONO_HWCAP_VAR(x86_has_fcmov)
+MONO_HWCAP_VAR(x86_has_sse1)
+MONO_HWCAP_VAR(x86_has_sse2)
+MONO_HWCAP_VAR(x86_has_sse3)
+MONO_HWCAP_VAR(x86_has_ssse3)
+MONO_HWCAP_VAR(x86_has_sse41)
+MONO_HWCAP_VAR(x86_has_sse42)
+MONO_HWCAP_VAR(x86_has_sse4a)
+
+#endif
index 4a96aa3a088eeb3d6a646c123c603bb305c29296..5d72a4c7e2030260e74b82369ffc82db450636f4 100644 (file)
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
-#include "mono/utils/mono-hwcap-x86.h"
+#include "mono/utils/mono-hwcap.h"
 
 #if defined(HAVE_UNISTD_H)
 #include <unistd.h>
 #endif
-
 #if defined(_MSC_VER)
 #include <intrin.h>
 #endif
 
-gboolean mono_hwcap_x86_is_xen = FALSE;
-gboolean mono_hwcap_x86_has_cmov = FALSE;
-gboolean mono_hwcap_x86_has_fcmov = FALSE;
-gboolean mono_hwcap_x86_has_sse1 = FALSE;
-gboolean mono_hwcap_x86_has_sse2 = FALSE;
-gboolean mono_hwcap_x86_has_sse3 = FALSE;
-gboolean mono_hwcap_x86_has_ssse3 = FALSE;
-gboolean mono_hwcap_x86_has_sse41 = FALSE;
-gboolean mono_hwcap_x86_has_sse42 = FALSE;
-gboolean mono_hwcap_x86_has_sse4a = FALSE;
-
 static gboolean
 cpuid (int id, int *p_eax, int *p_ebx, int *p_ecx, int *p_edx)
 {
@@ -162,18 +150,3 @@ mono_hwcap_arch_init (void)
        mono_hwcap_x86_is_xen = !access ("/proc/xen", F_OK);
 #endif
 }
-
-void
-mono_hwcap_print (FILE *f)
-{
-       g_fprintf (f, "mono_hwcap_x86_is_xen = %i\n", mono_hwcap_x86_is_xen);
-       g_fprintf (f, "mono_hwcap_x86_has_cmov = %i\n", mono_hwcap_x86_has_cmov);
-       g_fprintf (f, "mono_hwcap_x86_has_fcmov = %i\n", mono_hwcap_x86_has_fcmov);
-       g_fprintf (f, "mono_hwcap_x86_has_sse1 = %i\n", mono_hwcap_x86_has_sse1);
-       g_fprintf (f, "mono_hwcap_x86_has_sse2 = %i\n", mono_hwcap_x86_has_sse2);
-       g_fprintf (f, "mono_hwcap_x86_has_sse3 = %i\n", mono_hwcap_x86_has_sse3);
-       g_fprintf (f, "mono_hwcap_x86_has_ssse3 = %i\n", mono_hwcap_x86_has_ssse3);
-       g_fprintf (f, "mono_hwcap_x86_has_sse41 = %i\n", mono_hwcap_x86_has_sse41);
-       g_fprintf (f, "mono_hwcap_x86_has_sse42 = %i\n", mono_hwcap_x86_has_sse42);
-       g_fprintf (f, "mono_hwcap_x86_has_sse4a = %i\n", mono_hwcap_x86_has_sse4a);
-}
diff --git a/mono/utils/mono-hwcap-x86.h b/mono/utils/mono-hwcap-x86.h
deleted file mode 100644 (file)
index 5e1f4f7..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef __MONO_UTILS_HWCAP_X86_H__
-#define __MONO_UTILS_HWCAP_X86_H__
-
-#include "mono/utils/mono-hwcap.h"
-
-extern gboolean mono_hwcap_x86_is_xen;
-extern gboolean mono_hwcap_x86_has_cmov;
-extern gboolean mono_hwcap_x86_has_fcmov;
-extern gboolean mono_hwcap_x86_has_sse1;
-extern gboolean mono_hwcap_x86_has_sse2;
-extern gboolean mono_hwcap_x86_has_sse3;
-extern gboolean mono_hwcap_x86_has_ssse3;
-extern gboolean mono_hwcap_x86_has_sse41;
-extern gboolean mono_hwcap_x86_has_sse42;
-extern gboolean mono_hwcap_x86_has_sse4a;
-
-#endif /* __MONO_UTILS_HWCAP_X86_H__ */
index a3d2b6078bfdb0d3e401d6e2854497e5ec7f3b8f..00fad690193a5f8415f4afc317b1c28afa97fd99 100644 (file)
 
 #include "mono/utils/mono-hwcap.h"
 
+#define MONO_HWCAP_VAR(NAME) gboolean mono_hwcap_ ## NAME = FALSE;
+#include "mono/utils/mono-hwcap-vars.h"
+#undef MONO_HWCAP_VAR
+
 static gboolean hwcap_inited = FALSE;
 
 void
@@ -35,19 +39,21 @@ mono_hwcap_init (void)
        if (hwcap_inited)
                return;
 
-#ifdef MONO_CROSS_COMPILE
-       /*
-        * If we're cross-compiling, we want to be as
-        * conservative as possible so that we produce
-        * code that's portable. Default to that.
-        */
-       if (!conservative)
-               conservative = "1";
-#endif
-
        if (!conservative || strncmp (conservative, "1", 1))
                mono_hwcap_arch_init ();
 
        if (verbose && !strncmp (verbose, "1", 1))
-               mono_hwcap_print (stdout);
+               mono_hwcap_print ();
+}
+
+void
+mono_hwcap_print (void)
+{
+       g_print ("[mono-hwcap] Detected following hardware capabilities:\n\n");
+
+#define MONO_HWCAP_VAR(NAME) g_print ("\t" #NAME " = %s\n", mono_hwcap_ ## NAME ? "yes" : "no");
+#include "mono/utils/mono-hwcap-vars.h"
+#undef MONO_HWCAP_VAR
+
+       g_print ("\n");
 }
index af5d665426905beefe8e3e89318e82e1a2610f49..1867d3d258a62bbb0c0e4d8b820892a691781586 100644 (file)
@@ -8,6 +8,10 @@
 
 #include "mono/utils/mono-compiler.h"
 
+#define MONO_HWCAP_VAR(NAME) extern gboolean mono_hwcap_ ## NAME;
+#include "mono/utils/mono-hwcap-vars.h"
+#undef MONO_HWCAP_VAR
+
 /* Call this function to perform hardware feature detection. Until
  * this function has been called, all feature variables will be
  * FALSE as a default.
  * result in an inconsistent state of the variables. Further,
  * feature variables should not be read *while* this function is
  * executing.
- *
- * To get at feature variables, include the appropriate header,
- * e.g. mono-hwcap-x86.h for x86(-64).
  */
 void mono_hwcap_init (void);
 
 /* Implemented in mono-hwcap-$TARGET.c. Do not call. */
 void mono_hwcap_arch_init (void);
 
-/* Print detected features to the given file. */
-void mono_hwcap_print (FILE *f);
+/* Print detected features to stdout. */
+void mono_hwcap_print (void);
 
 /* Please note: If you're going to use the Linux auxiliary vector
  * to detect CPU features, don't use any of the constant names in
index f076034da21d7f0dc9ff4aa6c3e1e535f20c8ef5..ea11fcc634bbc948e11af5338c56f1304cdc6f31 100644 (file)
@@ -25,7 +25,7 @@ mask (gpointer n, uintptr_t bit)
 }
 
 gpointer
-get_hazardous_pointer_with_mask (gpointer volatile *pp, MonoThreadHazardPointers *hp, int hazard_index)
+mono_lls_get_hazardous_pointer_with_mask (gpointer volatile *pp, MonoThreadHazardPointers *hp, int hazard_index)
 {
        gpointer p;
 
@@ -56,28 +56,21 @@ get_hazardous_pointer_with_mask (gpointer volatile *pp, MonoThreadHazardPointers
 /*
 Initialize @list and will use @free_node_func to release memory.
 If @free_node_func is null the caller is responsible for releasing node memory.
-If @free_node_func may lock, @free_node_func_locking must be
-HAZARD_FREE_MAY_LOCK; otherwise, HAZARD_FREE_NO_LOCK. It is ignored if
-@free_node_func is null.
 */
 void
-mono_lls_init (MonoLinkedListSet *list, void (*free_node_func)(void *), HazardFreeLocking free_node_func_locking)
+mono_lls_init (MonoLinkedListSet *list, void (*free_node_func)(void *))
 {
        list->head = NULL;
        list->free_node_func = free_node_func;
-       list->locking = free_node_func_locking;
 }
 
 /*
 Search @list for element with key @key.
-@context specifies whether the function is being called from a lock-free (i.e.
-signal handler or world stopped) context. It is only relevant if a node free
-function was given.
 The nodes next, cur and prev are returned in @hp.
 Returns true if a node with key @key was found.
 */
 gboolean
-mono_lls_find (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, uintptr_t key, HazardFreeContext context)
+mono_lls_find (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, uintptr_t key)
 {
        MonoLinkedListSetNode *cur, *next;
        MonoLinkedListSetNode **prev;
@@ -95,12 +88,12 @@ try_again:
         */
        mono_hazard_pointer_set (hp, 2, prev);
 
-       cur = (MonoLinkedListSetNode *) get_hazardous_pointer_with_mask ((gpointer*)prev, hp, 1);
+       cur = (MonoLinkedListSetNode *) mono_lls_get_hazardous_pointer_with_mask ((gpointer*)prev, hp, 1);
 
        while (1) {
                if (cur == NULL)
                        return FALSE;
-               next = (MonoLinkedListSetNode *) get_hazardous_pointer_with_mask ((gpointer*)&cur->next, hp, 0);
+               next = (MonoLinkedListSetNode *) mono_lls_get_hazardous_pointer_with_mask ((gpointer*)&cur->next, hp, 0);
                cur_key = cur->key;
 
                /*
@@ -137,15 +130,12 @@ try_again:
 
 /*
 Insert @value into @list.
-@context specifies whether the function is being called from a lock-free (i.e.
-signal handler or world stopped) context. It is only relevant if a node free
-function was given.
 The nodes value, cur and prev are returned in @hp.
 Return true if @value was inserted by this call. If it returns FALSE, it's the caller
 resposibility to release memory.
 */
 gboolean
-mono_lls_insert (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value, HazardFreeContext context)
+mono_lls_insert (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value)
 {
        MonoLinkedListSetNode *cur, **prev;
        /*We must do a store barrier before inserting 
@@ -153,7 +143,7 @@ mono_lls_insert (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLink
        mono_memory_barrier ();
 
        while (1) {
-               if (mono_lls_find (list, hp, value->key, context))
+               if (mono_lls_find (list, hp, value->key))
                        return FALSE;
                cur = (MonoLinkedListSetNode *) mono_hazard_pointer_get_val (hp, 1);
                prev = (MonoLinkedListSetNode **) mono_hazard_pointer_get_val (hp, 2);
@@ -169,18 +159,15 @@ mono_lls_insert (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLink
 
 /*
 Search @list for element with key @key and remove it.
-@context specifies whether the function is being called from a lock-free (i.e.
-signal handler or world stopped) context. It is only relevant if a node free
-function was given.
 The nodes next, cur and prev are returned in @hp
 Returns true if @value was removed by this call.
 */
 gboolean
-mono_lls_remove (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value, HazardFreeContext context)
+mono_lls_remove (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value)
 {
        MonoLinkedListSetNode *cur, **prev, *next;
        while (1) {
-               if (!mono_lls_find (list, hp, value->key, context))
+               if (!mono_lls_find (list, hp, value->key))
                        return FALSE;
 
                next = (MonoLinkedListSetNode *) mono_hazard_pointer_get_val (hp, 0);
@@ -198,9 +185,9 @@ mono_lls_remove (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLink
                        mono_memory_write_barrier ();
                        mono_hazard_pointer_clear (hp, 1);
                        if (list->free_node_func)
-                               mono_thread_hazardous_try_free (value, list->free_node_func);
+                               mono_thread_hazardous_queue_free (value, list->free_node_func);
                } else
-                       mono_lls_find (list, hp, value->key, context);
+                       mono_lls_find (list, hp, value->key);
                return TRUE;
        }
 }
index 947602f0c34e2177d3a829fd6863850208d24c6f..ee4d77799ec50d1d54573851d4c20994899a21de 100644 (file)
@@ -24,7 +24,6 @@ struct _MonoLinkedListSetNode {
 typedef struct {
        MonoLinkedListSetNode *head;
        void (*free_node_func)(void *);
-       HazardFreeLocking locking;
 } MonoLinkedListSet;
 
 
@@ -45,20 +44,20 @@ Those are low level operations. prev, cur, next are returned in the hazard point
 You must manually clean the hazard pointer table after using them.
 */
 
-void
-mono_lls_init (MonoLinkedListSet *list, void (*free_node_func)(void *), HazardFreeLocking free_node_func_locking);
+MONO_API void
+mono_lls_init (MonoLinkedListSet *list, void (*free_node_func)(void *));
 
-gboolean
-mono_lls_find (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, uintptr_t key, HazardFreeContext context);
+MONO_API gboolean
+mono_lls_find (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, uintptr_t key);
 
-gboolean
-mono_lls_insert (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value, HazardFreeContext context);
+MONO_API gboolean
+mono_lls_insert (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value);
 
-gboolean
-mono_lls_remove (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value, HazardFreeContext context);
+MONO_API gboolean
+mono_lls_remove (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value);
 
-gpointer
-get_hazardous_pointer_with_mask (gpointer volatile *pp, MonoThreadHazardPointers *hp, int hazard_index);
+MONO_API gpointer
+mono_lls_get_hazardous_pointer_with_mask (gpointer volatile *pp, MonoThreadHazardPointers *hp, int hazard_index);
 
 static inline gboolean
 mono_lls_filter_accept_all (gpointer elem)
@@ -108,12 +107,12 @@ mono_lls_filter_accept_all (gpointer elem)
                        restart__ = FALSE; \
                        MonoLinkedListSetNode **prev__ = &list__->head; \
                        mono_hazard_pointer_set (hp__, 2, prev__); \
-                       MonoLinkedListSetNode *cur__ = (MonoLinkedListSetNode *) get_hazardous_pointer_with_mask ((gpointer *) prev__, hp__, 1); \
+                       MonoLinkedListSetNode *cur__ = (MonoLinkedListSetNode *) mono_lls_get_hazardous_pointer_with_mask ((gpointer *) prev__, hp__, 1); \
                        while (1) { \
                                if (!cur__) { \
                                        break; \
                                } \
-                               MonoLinkedListSetNode *next__ = (MonoLinkedListSetNode *) get_hazardous_pointer_with_mask ((gpointer *) &cur__->next, hp__, 0); \
+                               MonoLinkedListSetNode *next__ = (MonoLinkedListSetNode *) mono_lls_get_hazardous_pointer_with_mask ((gpointer *) &cur__->next, hp__, 0); \
                                uintptr_t ckey__ = cur__->key; \
                                mono_memory_read_barrier (); \
                                if (*prev__ != cur__) { \
index fa11aabcb7b2789f1a1b6f8f486a369bd8dee21c..cf73d9acbb84cbcafc5328dc5fb6b3b6f9975e50 100644 (file)
@@ -25,7 +25,7 @@
 #else
 #include <process.h>
 #endif
-#include "mono-logger.h"
+#include "mono-logger-internals.h"
 
 static FILE *logFile = NULL;
 static void *logUserData = NULL;
@@ -98,19 +98,17 @@ mono_log_open_logfile(const char *path, void *userData)
  *     @vargs - Variable argument list
  */
 void
-mono_log_write_logfile(const char *domain, GLogLevelFlags level, mono_bool hdr, const char *format, va_list args)
+mono_log_write_logfile (const char *log_domain, GLogLevelFlags level, mono_bool hdr, const char *message)
 {
        time_t t;
-       char logTime[80],       
-            logMessage[512];
-       pid_t pid;
-       int iLog = 0;
-       size_t nLog;
 
        if (logFile == NULL)
                logFile = stdout;
 
        if (hdr) {
+               pid_t pid;
+               char logTime [80];
+
 #ifndef HOST_WIN32
                struct tm tod;
                time(&t);
@@ -124,15 +122,14 @@ mono_log_write_logfile(const char *domain, GLogLevelFlags level, mono_bool hdr,
                pid = _getpid();
                strftime(logTime, sizeof(logTime), "%F %T", tod);
 #endif
-               iLog = sprintf(logMessage, "%s level[%c] mono[%d]: ",
-                              logTime,mapLogFileLevel(level),pid);
+               fprintf (logFile, "%s level[%c] mono[%d]: %s\n", logTime, mapLogFileLevel (level), pid, message);
+       } else {
+               fprintf (logFile, "%s%s%s\n",
+                       log_domain != NULL ? log_domain : "",
+                       log_domain != NULL ? ": " : "",
+                       message);
        }
-       nLog = sizeof(logMessage) - iLog - 2;
-       vsnprintf(logMessage+iLog, nLog, format, args);
-       iLog = strlen(logMessage);
-       logMessage[iLog++] = '\n';
-       logMessage[iLog++] = '\0';
-       fputs(logMessage, logFile);
+
        fflush(logFile);
 
        if (level == G_LOG_FLAG_FATAL)
index 1ce111c1762e2ee67fea21015345fa6ea4c7ffdb..388fd26202f6c5f4b2b936b6bf81592d6ed0d049 100644 (file)
@@ -25,7 +25,7 @@
 #include <errno.h>
 #include <time.h>
 #include <sys/time.h>
-#include "mono-logger.h"
+#include "mono-logger-internals.h"
 
 static void *logUserData = NULL;
 
@@ -70,7 +70,7 @@ mono_log_open_syslog(const char *ident, void *userData)
 }
 
 /**
- * mono_log_write_logfile
+ * mono_log_write_syslog
  *     
  *     Write data to the log file.
  *
@@ -80,9 +80,9 @@ mono_log_open_syslog(const char *ident, void *userData)
  *     @vargs - Variable argument list
  */
 void
-mono_log_write_syslog(const char *domain, GLogLevelFlags level, mono_bool hdr, const char *format, va_list args)
+mono_log_write_syslog(const char *domain, GLogLevelFlags level, mono_bool hdr, const char *message)
 {
-       vsyslog(mapSyslogLevel(level), format, args);
+       syslog (mapSyslogLevel(level), "%s", message);
 
        if (level == G_LOG_FLAG_FATAL)
                abort();
index 1746128a9384306ebbd0619ec95335eb08264ec4..d0ee01994371e00665dcea0f29e18634b377a66d 100644 (file)
@@ -23,7 +23,7 @@
 #include <errno.h>
 #include <time.h>
 #include <process.h>
-#include "mono-logger.h"
+#include "mono-logger-internals.h"
 
 static FILE *logFile = NULL;
 static void *logUserData = NULL;
@@ -85,31 +85,23 @@ mono_log_open_syslog(const char *ident, void *userData)
  *     @vargs - Variable argument list
  */
 void
-mono_log_write_syslog(const char *domain, GLogLevelFlags level, mono_bool hdr, const char *format, va_list args)
+mono_log_write_syslog(const char *domain, GLogLevelFlags level, mono_bool hdr, const char *message)
 {
        time_t t;
-       struct tm *tod;
-       char logTime[80],
-             logMessage[512];
        pid_t pid;
-       int iLog = 0;
-       size_t nLog;
+       char logTime [80];
 
        if (logFile == NULL)
-               mono_log_open_syslog(NULL, NULL);
+               logFile = stdout;
 
+       struct tm *tod;
        time(&t);
        tod = localtime(&t);
        pid = _getpid();
-       strftime(logTime, sizeof(logTime), "%Y-%m-%d %H:%M:%S", tod);
-       iLog = sprintf(logMessage, "%s level[%c] mono[%d]: ",
-                      logTime,mapLogFileLevel(level),pid);
-       nLog = sizeof(logMessage) - iLog - 2;
-       vsnprintf(logMessage+iLog, nLog, format, args);
-       iLog = strlen(logMessage);
-       logMessage[iLog++] = '\n';
-       logMessage[iLog++] = 0;
-       fputs(logMessage, logFile);
+       strftime(logTime, sizeof(logTime), "%F %T", tod);
+
+       fprintf (logFile, "%s level[%c] mono[%d]: %s\n", logTime, mapLogFileLevel (level), pid, message);
+
        fflush(logFile);
 
        if (level == G_LOG_FLAG_FATAL)
index f32a25e306d75f5a64ddd70ef84aaea354a290e2..57ef259677fd4b3ec81df0cadc1f70e6da914eb0 100644 (file)
@@ -149,6 +149,31 @@ mono_trace_message(MonoTraceMask mask, const char *format, ...)
 
 #endif
 
+/* Internal logging API */
+typedef void (*MonoLoggerOpen) (const char *, void *);
+typedef void (*MonoLoggerWrite) (const char *, GLogLevelFlags, mono_bool, const char *);
+typedef void (*MonoLoggerClose) (void);
+
+typedef struct _MonoLogCallParm_ {
+       MonoLoggerOpen  opener;         /* Routine to open logging */
+       MonoLoggerWrite writer;         /* Routine to write log data */
+       MonoLoggerClose closer;         /* Routine to close logging */
+       char            *dest;          /* Log destination */
+       void            *user_data;     /* User data from legacy handler */
+       mono_bool       header;         /* Whether we want pid/time/date in log message */
+} MonoLogCallParm;
+
+void mono_trace_set_log_handler_internal (MonoLogCallParm *callback, void *user_data);
+void mono_trace_set_logdest_string (const char *value);
+void mono_trace_set_logheader_string (const char *value);
+
+void mono_log_open_syslog (const char *, void *);
+void mono_log_write_syslog (const char *, GLogLevelFlags, mono_bool, const char *);
+void mono_log_close_syslog (void);
+
+void mono_log_open_logfile (const char *, void *);
+void mono_log_write_logfile (const char *, GLogLevelFlags, mono_bool, const char *);
+void mono_log_close_logfile (void);
 
 G_END_DECLS
 
index f6cdd40b20d8df63eb141fdebd1b721017e12899..20457c95b677c91eedb261eace27b409229db62d 100644 (file)
@@ -29,7 +29,7 @@ static MonoLogCallParm logCallback = {
 typedef struct {
    MonoLogCallback legacy_callback;
    gpointer user_data;
-} legacyLoggerUserData;
+} UserSuppliedLoggerUserData;
 
 /**
  * mono_trace_init:
@@ -81,19 +81,19 @@ mono_trace_cleanup (void)
 void 
 mono_tracev_inner (GLogLevelFlags level, MonoTraceMask mask, const char *format, va_list args)
 {
+       char *log_message;
        if (level_stack == NULL) {
                mono_trace_init ();
                if(level > mono_internal_current_level || !(mask & mono_internal_current_mask))
                        return;
        }
 
-       if (logCallback.opener == NULL) {
-               logCallback.opener = mono_log_open_logfile;
-               logCallback.writer = mono_log_write_logfile;
-               logCallback.closer = mono_log_close_logfile;
-               logCallback.opener(NULL, NULL);
-       }
-       logCallback.writer(mono_log_domain, level, logCallback.header, format, args);
+       g_assert (logCallback.opener); // mono_trace_init should have provided us with one!
+
+       if (g_vasprintf (&log_message, format, args) < 0)
+               return;
+       logCallback.writer (mono_log_domain, level, logCallback.header, log_message);
+       g_free (log_message);
 }
 
 /**
@@ -340,13 +340,19 @@ log_level_get_name (GLogLevelFlags log_level)
  * logging. We ignore the header request as legacy handlers never had headers.
  */
 static void
-callback_adapter(const char *domain, GLogLevelFlags level, mono_bool fatal, const char *fmt, va_list args)
+callback_adapter (const char *domain, GLogLevelFlags level, mono_bool fatal, const char *message)
 {
-       legacyLoggerUserData *ll = (legacyLoggerUserData *) logCallback.user_data;
-       const char *msg = g_strdup_vprintf (fmt, args);
+       UserSuppliedLoggerUserData *ll =logCallback.user_data;
 
-       ll->legacy_callback (domain, log_level_get_name(level), msg, fatal, ll->user_data);
-       g_free ((void *) msg);
+       ll->legacy_callback (domain, log_level_get_name(level), message, fatal, ll->user_data);
+}
+
+static void
+eglib_log_adapter (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
+{
+       UserSuppliedLoggerUserData *ll = logCallback.user_data;
+
+       ll->legacy_callback (log_domain, log_level_get_name (log_level), message, log_level & G_LOG_LEVEL_ERROR, ll->user_data);
 }
 
 /**
@@ -369,7 +375,7 @@ static void
 legacy_closer(void)
 {
        if (logCallback.user_data != NULL) {
-               g_free (logCallback.user_data); /* This is a LegacyLoggerUserData struct */
+               g_free (logCallback.user_data); /* This is a UserSuppliedLoggerUserData struct */
                logCallback.opener = NULL;      
                logCallback.writer = NULL;
                logCallback.closer = NULL;
@@ -386,15 +392,16 @@ legacy_closer(void)
  * 
  * The log handler replaces the default runtime logger. All logging requests with be routed to it.
  * If the fatal argument in the callback is true, the callback must abort the current process. The runtime expects that
- * execution will not resume after a fatal error. This is for "old-style" or legacy log handers.
+ * execution will not resume after a fatal error.
  */
 void
 mono_trace_set_log_handler (MonoLogCallback callback, void *user_data)
 {
-        g_assert (callback);
+       g_assert (callback);
+
        if (logCallback.closer != NULL)
                logCallback.closer();
-       legacyLoggerUserData *ll = g_malloc (sizeof (legacyLoggerUserData));
+       UserSuppliedLoggerUserData *ll = g_malloc (sizeof (UserSuppliedLoggerUserData));
        ll->legacy_callback = callback;
        ll->user_data = user_data;
        logCallback.opener = legacy_opener;
@@ -402,6 +409,14 @@ mono_trace_set_log_handler (MonoLogCallback callback, void *user_data)
        logCallback.closer = legacy_closer;
        logCallback.user_data = ll;
        logCallback.dest = NULL;
+
+       g_log_set_default_handler (eglib_log_adapter, user_data);
+}
+
+static void
+structured_log_adapter (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
+{
+       logCallback.writer (log_domain, log_level, logCallback.header, message);
 }
 
 /**
@@ -425,7 +440,9 @@ mono_trace_set_log_handler_internal (MonoLogCallParm *callback, void *user_data)
        logCallback.closer = callback->closer;
        logCallback.header = mono_trace_log_header;
        logCallback.dest   = callback->dest;
-       logCallback.opener(logCallback.dest, user_data);
+       logCallback.opener (logCallback.dest, user_data);
+
+       g_log_set_default_handler (structured_log_adapter, user_data);
 }
 
 static void
index 073daf1c87a16260f452584f96026e771eff8167..5f0943d5e1d698981354c2c86604edda6255d204 100644 (file)
@@ -10,32 +10,9 @@ mono_trace_set_level_string (const char *value);
 MONO_API void 
 mono_trace_set_mask_string (const char *value);
 
-MONO_API void 
-mono_trace_set_logdest_string (const char *value);
-
-MONO_API void 
-mono_trace_set_logheader_string (const char *value);
-
 typedef void (*MonoPrintCallback) (const char *string, mono_bool is_stdout);
 typedef void (*MonoLogCallback) (const char *log_domain, const char *log_level, const char *message, mono_bool fatal, void *user_data);
 
-
-typedef void (*MonoLoggerOpen) (const char *, void *);
-typedef void (*MonoLoggerWrite) (const char *, GLogLevelFlags, mono_bool, const char *, va_list);
-typedef void (*MonoLoggerClose) (void);
-
-typedef struct _MonoLogCallParm_ {
-       MonoLoggerOpen  opener;         /* Routine to open logging */
-       MonoLoggerWrite writer;         /* Routine to write log data */
-       MonoLoggerClose closer;         /* Routine to close logging */
-       char            *dest;          /* Log destination */
-       void            *user_data;     /* User data from legacy handler */
-       mono_bool       header;         /* Whether we want pid/time/date in log message */
-} MonoLogCallParm;
-
-void
-mono_trace_set_log_handler_internal (MonoLogCallParm *callback, void *user_data);
-
 MONO_API void
 mono_trace_set_log_handler (MonoLogCallback callback, void *user_data);
 
@@ -45,24 +22,6 @@ mono_trace_set_print_handler (MonoPrintCallback callback);
 MONO_API void
 mono_trace_set_printerr_handler (MonoPrintCallback callback);
 
-MONO_API void
-mono_log_open_syslog(const char *, void *);
-
-MONO_API void
-mono_log_write_syslog(const char *, GLogLevelFlags, mono_bool, const char *, va_list);
-
-MONO_API void
-mono_log_close_syslog(void);
-
-MONO_API void
-mono_log_open_logfile(const char *, void *);
-
-MONO_API void
-mono_log_write_logfile(const char *, GLogLevelFlags, mono_bool, const char *, va_list);
-
-MONO_API void
-mono_log_close_logfile(void);
-
 MONO_END_DECLS
 
 #endif /* __MONO_LOGGER_H__ */
index 60f6164dc4511921906c9076701ea86db707f50e..b59ffff85f93b28573c3089420381f8eeef6b484 100644 (file)
@@ -56,21 +56,6 @@ static inline void mono_memory_read_barrier (void)
        mono_memory_barrier ();
 }
 
-static inline void mono_memory_write_barrier (void)
-{
-       mono_memory_barrier ();
-}
-#elif defined(__ia64__)
-static inline void mono_memory_barrier (void)
-{
-       __asm__ __volatile__ ("mf" : : : "memory");
-}
-
-static inline void mono_memory_read_barrier (void)
-{
-       mono_memory_barrier ();
-}
-
 static inline void mono_memory_write_barrier (void)
 {
        mono_memory_barrier ();
index efd732d6d56b7592b9de709a4d34c352e42baf8f..7a589314f1f43b5032ec78182bd4a377e00ba22e 100644 (file)
 #    define kinfo_starttime_member kp_proc.p_starttime
 #    define kinfo_pid_member kp_proc.p_pid
 #    define kinfo_name_member kp_proc.p_comm
+#elif defined(__NetBSD__)
+#    define kinfo_starttime_member p_ustart_sec
+#    define kinfo_pid_member p_pid
+#    define kinfo_name_member p_comm
 #elif defined(__OpenBSD__)
 // Can not figure out how to get the proc's start time on OpenBSD
 #    undef kinfo_starttime_member 
@@ -317,8 +321,16 @@ mono_process_get_times (gpointer pid, gint64 *start_time, gint64 *user_time, gin
                {
                        KINFO_PROC processi;
 
-                       if (sysctl_kinfo_proc (pid, &processi))
+                       if (sysctl_kinfo_proc (pid, &processi)) {
+#if defined(__NetBSD__)
+                               struct timeval tv;
+                               tv.tv_sec = processi.kinfo_starttime_member;
+                               tv.tv_usec = processi.p_ustart_usec;
+                               *start_time = mono_100ns_datetime_from_timeval(tv);
+#else
                                *start_time = mono_100ns_datetime_from_timeval (processi.kinfo_starttime_member);
+#endif
+                       }
                }
 #endif
 
index 1e8297750bfb64858fe3f25ec5b5e30bc2b96ede..0e5a85384705341e3c5233e0db110fae07201803 100644 (file)
@@ -165,27 +165,27 @@ static void
 get_entropy_from_egd (const char *path, guchar *buffer, int buffer_size, MonoError *error)
 {
        struct sockaddr_un egd_addr;
-       gint file;
+       gint socket_fd;
        gint ret;
        guint offset = 0;
        int err = 0;
 
        mono_error_init (error);
        
-       file = socket (PF_UNIX, SOCK_STREAM, 0);
-       if (file < 0) {
+       socket_fd = socket (PF_UNIX, SOCK_STREAM, 0);
+       if (socket_fd < 0) {
                ret = -1;
                err = errno;
        } else {
                egd_addr.sun_family = AF_UNIX;
                strncpy (egd_addr.sun_path, path, sizeof (egd_addr.sun_path) - 1);
                egd_addr.sun_path [sizeof (egd_addr.sun_path) - 1] = '\0';
-               ret = connect (file, (struct sockaddr*) &egd_addr, sizeof (egd_addr));
+               ret = connect (socket_fd, (struct sockaddr*) &egd_addr, sizeof (egd_addr));
                err = errno;
        }
        if (ret == -1) {
-               if (file >= 0)
-                       close (file);
+               if (socket_fd >= 0)
+                       close (socket_fd);
                g_warning ("Entropy problem! Can't create or connect to egd socket %s", path);
                mono_error_set_execution_engine (error, "Failed to open egd socket %s: %s", path, strerror (err));
                return;
@@ -199,14 +199,14 @@ get_entropy_from_egd (const char *path, guchar *buffer, int buffer_size, MonoErr
                request [0] = 2;
                request [1] = buffer_size < 255 ? buffer_size : 255;
                while (count < 2) {
-                       int sent = write (file, request + count, 2 - count);
+                       int sent = write (socket_fd, request + count, 2 - count);
                        err = errno;
                        if (sent >= 0) {
                                count += sent;
                        } else if (err == EINTR) {
                                continue;
                        } else {
-                               close (file);
+                               close (socket_fd);
                                g_warning ("Send egd request failed %d", err);
                                mono_error_set_execution_engine (error, "Failed to send request to egd socket: %s", strerror (err));
                                return;
@@ -216,7 +216,7 @@ get_entropy_from_egd (const char *path, guchar *buffer, int buffer_size, MonoErr
                count = 0;
                while (count != request [1]) {
                        int received;
-                       received = read (file, buffer + offset, request [1] - count);
+                       received = read (socket_fd, buffer + offset, request [1] - count);
                        err = errno;
                        if (received > 0) {
                                count += received;
@@ -224,7 +224,7 @@ get_entropy_from_egd (const char *path, guchar *buffer, int buffer_size, MonoErr
                        } else if (received < 0 && err == EINTR) {
                                continue;
                        } else {
-                               close (file);
+                               close (socket_fd);
                                g_warning ("Receive egd request failed %d", err);
                                mono_error_set_execution_engine (error, "Failed to get response from egd socket: %s", strerror(err));
                                return;
@@ -234,7 +234,7 @@ get_entropy_from_egd (const char *path, guchar *buffer, int buffer_size, MonoErr
                buffer_size -= request [1];
        }
 
-       close (file);
+       close (socket_fd);
 }
 
 gboolean
index cbf92bb1ce763ee726ca92b17688d746d38089d2..67b470467b96339e10e560a26f99a1f2ee644b07 100644 (file)
@@ -40,140 +40,39 @@ extern int tkill (pid_t tid, int signal);
 void nacl_shutdown_gc_thread(void);
 #endif
 
-typedef struct {
-       pthread_t id;
-       GPtrArray *owned_mutexes;
-       gint32 priority;
-} MonoW32HandleThread;
-
-static gpointer
-thread_handle_create (void)
+void
+mono_threads_platform_register (MonoThreadInfo *info)
 {
-       MonoW32HandleThread thread_data;
        gpointer thread_handle;
 
-       thread_data.id = pthread_self ();
-       thread_data.owned_mutexes = g_ptr_array_new ();
-       thread_data.priority = MONO_THREAD_PRIORITY_NORMAL;
+       info->owned_mutexes = g_ptr_array_new ();
+       info->priority = MONO_THREAD_PRIORITY_NORMAL;
 
-       thread_handle = mono_w32handle_new (MONO_W32HANDLE_THREAD, (gpointer) &thread_data);
+       thread_handle = mono_w32handle_new (MONO_W32HANDLE_THREAD, NULL);
        if (thread_handle == INVALID_HANDLE_VALUE)
-               return NULL;
+               g_error ("%s: failed to create handle", __func__);
 
        /* We need to keep the handle alive, as long as the corresponding managed
         * thread object is alive. The handle is going to be unref when calling
         * the finalizer on the MonoThreadInternal object */
        mono_w32handle_ref (thread_handle);
 
-       return thread_handle;
-}
-
-static int
-win32_priority_to_posix_priority (MonoThreadPriority priority, int policy)
-{
-       g_assert (priority >= MONO_THREAD_PRIORITY_LOWEST);
-       g_assert (priority <= MONO_THREAD_PRIORITY_HIGHEST);
-
-/* Necessary to get valid priority range */
-#ifdef _POSIX_PRIORITY_SCHEDULING
-       int max, min;
-
-       min = sched_get_priority_min (policy);
-       max = sched_get_priority_max (policy);
-
-       /* Partition priority range linearly (cross-multiply) */
-       if (max > 0 && min >= 0 && max > min)
-               return (int)((double) priority * (max - min) / (MONO_THREAD_PRIORITY_HIGHEST - MONO_THREAD_PRIORITY_LOWEST));
-#endif
-
-       switch (policy) {
-       case SCHED_FIFO:
-       case SCHED_RR:
-               return 50;
-#ifdef SCHED_BATCH
-       case SCHED_BATCH:
-#endif
-       case SCHED_OTHER:
-               return 0;
-       default:
-               return -1;
-       }
-}
-
-typedef struct {
-       void *(*start_routine)(void*);
-       void *arg;
-       int flags;
-       gint32 priority;
-       MonoCoopSem registered;
-       HANDLE handle;
-} StartInfo;
-
-static void*
-inner_start_thread (void *arg)
-{
-       StartInfo *start_info = (StartInfo *) arg;
-       void *t_arg = start_info->arg;
-       int res;
-       void *(*start_func)(void*) = start_info->start_routine;
-       guint32 flags = start_info->flags;
-       void *result;
-       HANDLE handle;
-       MonoThreadInfo *info;
-
-       /* Register the thread with the io-layer */
-       handle = thread_handle_create ();
-       if (!handle) {
-               mono_coop_sem_post (&(start_info->registered));
-               return NULL;
-       }
-       start_info->handle = handle;
-
-       info = mono_thread_info_attach (&result);
-
-       info->runtime_thread = TRUE;
-       info->handle = handle;
-
-       mono_threads_platform_set_priority (info, start_info->priority);
-
-       if (flags & CREATE_SUSPENDED) {
-               info->create_suspended = TRUE;
-               mono_coop_sem_init (&info->create_suspended_sem, 0);
-       }
-
-       /* start_info is not valid after this */
-       mono_coop_sem_post (&(start_info->registered));
-       start_info = NULL;
-
-       if (flags & CREATE_SUSPENDED) {
-               res = mono_coop_sem_wait (&info->create_suspended_sem, MONO_SEM_FLAGS_NONE);
-               g_assert (res != -1);
-
-               mono_coop_sem_destroy (&info->create_suspended_sem);
-       }
-
-       /* Run the actual main function of the thread */
-       result = start_func (t_arg);
-
-       mono_threads_platform_exit (GPOINTER_TO_UINT (result));
-       g_assert_not_reached ();
+       g_assert (!info->handle);
+       info->handle = thread_handle;
 }
 
-HANDLE
-mono_threads_platform_create_thread (MonoThreadStart start_routine, gpointer arg, MonoThreadParm *tp, MonoNativeThreadId *out_tid)
+int
+mono_threads_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_data, gsize stack_size, MonoNativeThreadId *out_tid)
 {
        pthread_attr_t attr;
-       int res;
        pthread_t thread;
-       StartInfo start_info;
-       guint32 stack_size;
-       int policy;
-       struct sched_param sp;
+       gint res;
 
        res = pthread_attr_init (&attr);
        g_assert (!res);
 
-       if (tp->stack_size == 0) {
+#ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
+       if (stack_size == 0) {
 #if HAVE_VALGRIND_MEMCHECK_H
                if (RUNNING_ON_VALGRIND)
                        stack_size = 1 << 20;
@@ -182,63 +81,26 @@ mono_threads_platform_create_thread (MonoThreadStart start_routine, gpointer arg
 #else
                stack_size = (SIZEOF_VOID_P / 4) * 1024 * 1024;
 #endif
-       } else
-               stack_size = tp->stack_size;
+       }
 
 #ifdef PTHREAD_STACK_MIN
        if (stack_size < PTHREAD_STACK_MIN)
                stack_size = PTHREAD_STACK_MIN;
 #endif
 
-#ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
        res = pthread_attr_setstacksize (&attr, stack_size);
        g_assert (!res);
-#endif
-
-       /*
-        * For policies that respect priorities set the prirority for the new thread
-        */ 
-       pthread_getschedparam(pthread_self(), &policy, &sp);
-       if ((policy == SCHED_FIFO) || (policy == SCHED_RR)) {
-               sp.sched_priority = win32_priority_to_posix_priority (tp->priority, policy);
-               res = pthread_attr_setschedparam (&attr, &sp);
-       }
-
-       memset (&start_info, 0, sizeof (StartInfo));
-       start_info.start_routine = (void *(*)(void *)) start_routine;
-       start_info.arg = arg;
-       start_info.flags = tp->creation_flags;
-       start_info.priority = tp->priority;
-       mono_coop_sem_init (&(start_info.registered), 0);
+#endif /* HAVE_PTHREAD_ATTR_SETSTACKSIZE */
 
        /* Actually start the thread */
-       res = mono_gc_pthread_create (&thread, &attr, inner_start_thread, &start_info);
-       if (res) {
-               mono_coop_sem_destroy (&(start_info.registered));
-               return NULL;
-       }
-
-       /* Wait until the thread register itself in various places */
-       res = mono_coop_sem_wait (&start_info.registered, MONO_SEM_FLAGS_NONE);
-       g_assert (res != -1);
-
-       mono_coop_sem_destroy (&(start_info.registered));
+       res = mono_gc_pthread_create (&thread, &attr, (gpointer (*)(gpointer)) thread_fn, thread_data);
+       if (res)
+               return -1;
 
        if (out_tid)
                *out_tid = thread;
 
-       return start_info.handle;
-}
-
-/*
- * mono_threads_platform_resume_created:
- *
- *   Resume a newly created thread created using CREATE_SUSPENDED.
- */
-void
-mono_threads_platform_resume_created (MonoThreadInfo *info, MonoNativeThreadId tid)
-{
-       mono_coop_sem_post (&info->create_suspended_sem);
+       return 0;
 }
 
 gboolean
@@ -250,14 +112,10 @@ mono_threads_platform_yield (void)
 void
 mono_threads_platform_exit (int exit_code)
 {
-       MonoThreadInfo *current = mono_thread_info_current ();
-
 #if defined(__native_client__)
        nacl_shutdown_gc_thread();
 #endif
 
-       mono_threads_platform_set_exited (current);
-
        mono_thread_info_detach ();
 
        pthread_exit (NULL);
@@ -266,25 +124,7 @@ mono_threads_platform_exit (int exit_code)
 void
 mono_threads_platform_unregister (MonoThreadInfo *info)
 {
-       if (info->handle) {
-               mono_threads_platform_set_exited (info);
-               info->handle = NULL;
-       }
-}
-
-HANDLE
-mono_threads_platform_open_handle (void)
-{
-       MonoThreadInfo *info;
-
-       info = mono_thread_info_current ();
-       g_assert (info);
-
-       if (!info->handle)
-               info->handle = thread_handle_create ();
-       else
-               mono_w32handle_ref (info->handle);
-       return info->handle;
+       mono_threads_platform_set_exited (info);
 }
 
 int
@@ -309,6 +149,12 @@ mono_threads_platform_open_thread_handle (HANDLE handle, MonoNativeThreadId tid)
        return handle;
 }
 
+void
+mono_threads_platform_close_thread_handle (HANDLE handle)
+{
+       mono_w32handle_unref (handle);
+}
+
 int
 mono_threads_pthread_kill (MonoThreadInfo *info, int signum)
 {
@@ -400,31 +246,28 @@ mono_native_thread_set_name (MonoNativeThreadId tid, const char *name)
 void
 mono_threads_platform_set_exited (MonoThreadInfo *info)
 {
-       MonoW32HandleThread *thread_data;
        gpointer mutex_handle;
        int i, thr_ret;
        pid_t pid;
        pthread_t tid;
 
-       if (!info->handle || mono_w32handle_issignalled (info->handle) || mono_w32handle_get_type (info->handle) == MONO_W32HANDLE_UNUSED) {
-               /* We must have already deliberately finished
-                * with this thread, so don't do any more now */
-               return;
-       }
+       g_assert (info->handle);
 
-       if (!mono_w32handle_lookup (info->handle, MONO_W32HANDLE_THREAD, (gpointer*) &thread_data))
-               g_error ("unknown thread handle %p", info->handle);
+       if (mono_w32handle_issignalled (info->handle))
+               g_error ("%s: handle %p thread %p has already exited, it's handle is signalled", __func__, info->handle, mono_thread_info_get_tid (info));
+       if (mono_w32handle_get_type (info->handle) == MONO_W32HANDLE_UNUSED)
+               g_error ("%s: handle %p thread %p has already exited, it's handle type is 'unused'", __func__, info->handle, mono_thread_info_get_tid (info));
 
        pid = wapi_getpid ();
        tid = pthread_self ();
 
-       for (i = 0; i < thread_data->owned_mutexes->len; i++) {
-               mutex_handle = g_ptr_array_index (thread_data->owned_mutexes, i);
+       for (i = 0; i < info->owned_mutexes->len; i++) {
+               mutex_handle = g_ptr_array_index (info->owned_mutexes, i);
                wapi_mutex_abandon (mutex_handle, pid, tid);
                mono_thread_info_disown_mutex (info, mutex_handle);
        }
 
-       g_ptr_array_free (thread_data->owned_mutexes, TRUE);
+       g_ptr_array_free (info->owned_mutexes, TRUE);
 
        thr_ret = mono_w32handle_lock_handle (info->handle);
        g_assert (thr_ret == 0);
@@ -443,120 +286,102 @@ mono_threads_platform_set_exited (MonoThreadInfo *info)
 void
 mono_threads_platform_describe (MonoThreadInfo *info, GString *text)
 {
-       MonoW32HandleThread *thread_data;
        int i;
 
-       g_assert (info->handle);
-
-       if (!mono_w32handle_lookup (info->handle, MONO_W32HANDLE_THREAD, (gpointer*) &thread_data))
-               g_error ("unknown thread handle %p", info->handle);
-
        g_string_append_printf (text, "thread handle %p state : ", info->handle);
 
        mono_thread_info_describe_interrupt_token (info, text);
 
        g_string_append_printf (text, ", owns (");
-       for (i = 0; i < thread_data->owned_mutexes->len; i++)
-               g_string_append_printf (text, i > 0 ? ", %p" : "%p", g_ptr_array_index (thread_data->owned_mutexes, i));
+       for (i = 0; i < info->owned_mutexes->len; i++)
+               g_string_append_printf (text, i > 0 ? ", %p" : "%p", g_ptr_array_index (info->owned_mutexes, i));
        g_string_append_printf (text, ")");
 }
 
 void
 mono_threads_platform_own_mutex (MonoThreadInfo *info, gpointer mutex_handle)
 {
-       MonoW32HandleThread *thread_data;
-
-       g_assert (info->handle);
-
-       if (!mono_w32handle_lookup (info->handle, MONO_W32HANDLE_THREAD, (gpointer*) &thread_data))
-               g_error ("unknown thread handle %p", info->handle);
-
        mono_w32handle_ref (mutex_handle);
 
-       g_ptr_array_add (thread_data->owned_mutexes, mutex_handle);
+       g_ptr_array_add (info->owned_mutexes, mutex_handle);
 }
 
 void
 mono_threads_platform_disown_mutex (MonoThreadInfo *info, gpointer mutex_handle)
 {
-       MonoW32HandleThread *thread_data;
-
-       g_assert (info->handle);
-
-       if (!mono_w32handle_lookup (info->handle, MONO_W32HANDLE_THREAD, (gpointer*) &thread_data))
-               g_error ("unknown thread handle %p", info->handle);
-
        mono_w32handle_unref (mutex_handle);
 
-       g_ptr_array_remove (thread_data->owned_mutexes, mutex_handle);
+       g_ptr_array_remove (info->owned_mutexes, mutex_handle);
 }
 
 MonoThreadPriority
 mono_threads_platform_get_priority (MonoThreadInfo *info)
 {
-       MonoW32HandleThread *thread_data;
-
-       g_assert (info->handle);
-
-       if (!mono_w32handle_lookup (info->handle, MONO_W32HANDLE_THREAD, (gpointer *)&thread_data))
-               return MONO_THREAD_PRIORITY_NORMAL;
-
-       return thread_data->priority;
+       return info->priority;
 }
 
-gboolean
+void
 mono_threads_platform_set_priority (MonoThreadInfo *info, MonoThreadPriority priority)
 {
-       MonoW32HandleThread *thread_data;
-       int policy, posix_priority;
+       int policy;
        struct sched_param param;
+       pthread_t tid;
+       gint res;
 
-       g_assert (info->handle);
+       g_assert (priority >= MONO_THREAD_PRIORITY_LOWEST);
+       g_assert (priority <= MONO_THREAD_PRIORITY_HIGHEST);
+       g_assert (MONO_THREAD_PRIORITY_LOWEST < MONO_THREAD_PRIORITY_HIGHEST);
 
-       if (!mono_w32handle_lookup (info->handle, MONO_W32HANDLE_THREAD, (gpointer*) &thread_data))
-               return FALSE;
-
-       switch (pthread_getschedparam (thread_data->id, &policy, &param)) {
-       case 0:
-               break;
-       case ESRCH:
-               g_warning ("pthread_getschedparam: error looking up thread id %x", (gsize)thread_data->id);
-               return FALSE;
-       default:
-               return FALSE;
-       }
+       tid = mono_thread_info_get_tid (info);
 
-       posix_priority =  win32_priority_to_posix_priority (priority, policy);
-       if (posix_priority < 0)
-               return FALSE;
-
-       param.sched_priority = posix_priority;
-       switch (pthread_setschedparam (thread_data->id, policy, &param)) {
-       case 0:
-               break;
-       case ESRCH:
-               g_warning ("%s: pthread_setschedprio: error looking up thread id %x", __func__, (gsize)thread_data->id);
-               return FALSE;
-       case ENOTSUP:
-               g_warning ("%s: priority %d not supported", __func__, priority);
-               return FALSE;
-       case EPERM:
-               g_warning ("%s: permission denied", __func__);
-               return FALSE;
-       default:
-               return FALSE;
-       }
+       res = pthread_getschedparam (tid, &policy, &param);
+       if (res != 0)
+               g_error ("%s: pthread_getschedparam failed, error: \"%s\" (%d)", g_strerror (res), res);
 
-       thread_data->priority = priority;
-       return TRUE;
+#ifdef _POSIX_PRIORITY_SCHEDULING
+       int max, min;
 
-}
+       /* Necessary to get valid priority range */
 
-static void thread_details (gpointer data)
-{
-       MonoW32HandleThread *thread = (MonoW32HandleThread*) data;
-       g_print ("id: %p, owned_mutexes: %d, priority: %d",
-               thread->id, thread->owned_mutexes->len, thread->priority);
+       min = sched_get_priority_min (policy);
+       max = sched_get_priority_max (policy);
+
+       if (max > 0 && min >= 0 && max > min) {
+               double srange, drange, sposition, dposition;
+               srange = MONO_THREAD_PRIORITY_HIGHEST - MONO_THREAD_PRIORITY_LOWEST;
+               drange = max - min;
+               sposition = priority - MONO_THREAD_PRIORITY_LOWEST;
+               dposition = (sposition / srange) * drange;
+               param.sched_priority = (int)(dposition + min);
+       } else
+#endif
+       {
+               switch (policy) {
+               case SCHED_FIFO:
+               case SCHED_RR:
+                       param.sched_priority = 50;
+                       break;
+#ifdef SCHED_BATCH
+               case SCHED_BATCH:
+#endif
+               case SCHED_OTHER:
+                       param.sched_priority = 0;
+                       break;
+               default:
+                       g_error ("%s: unknown policy %d", __func__, policy);
+               }
+       }
+
+       res = pthread_setschedparam (tid, policy, &param);
+       if (res != 0) {
+               if (res == EPERM) {
+                       g_warning ("%s: pthread_setschedparam failed, error: \"%s\" (%d)", g_strerror (res), res);
+                       return;
+               }
+               g_error ("%s: pthread_setschedparam failed, error: \"%s\" (%d)", g_strerror (res), res);
+       }
+
+       info->priority = priority;
 }
 
 static const gchar* thread_typename (void)
@@ -566,7 +391,7 @@ static const gchar* thread_typename (void)
 
 static gsize thread_typesize (void)
 {
-       return sizeof (MonoW32HandleThread);
+       return 0;
 }
 
 static MonoW32HandleOps thread_ops = {
@@ -576,7 +401,7 @@ static MonoW32HandleOps thread_ops = {
        NULL,                           /* is_owned */
        NULL,                           /* special_wait */
        NULL,                           /* prewait */
-       thread_details,         /* details */
+       NULL,                           /* details */
        thread_typename,        /* typename */
        thread_typesize,        /* typesize */
 };
@@ -630,9 +455,6 @@ mono_threads_suspend_register (MonoThreadInfo *info)
 #if defined (PLATFORM_ANDROID)
        info->native_handle = gettid ();
 #endif
-
-       g_assert (!info->handle);
-       info->handle = thread_handle_create ();
 }
 
 void
index b926791f0621f7dd5e0a57dba29569ae6b10815a..4f8495054334310bb2f7289e8778e657915e59f2 100644 (file)
@@ -121,8 +121,6 @@ mono_threads_suspend_begin_async_resume (MonoThreadInfo *info)
 void
 mono_threads_suspend_register (MonoThreadInfo *info)
 {
-       g_assert (!info->handle);
-       info->handle = mono_threads_platform_open_handle();
 }
 
 void
@@ -134,88 +132,40 @@ mono_threads_suspend_free (MonoThreadInfo *info)
 
 #if defined (HOST_WIN32)
 
-typedef struct {
-       LPTHREAD_START_ROUTINE start_routine;
-       void *arg;
-       gint32 priority;
-       MonoCoopSem registered;
-       gboolean suspend;
-       HANDLE suspend_event;
-} ThreadStartInfo;
-
-static DWORD WINAPI
-inner_start_thread (LPVOID arg)
+void
+mono_threads_platform_register (MonoThreadInfo *info)
 {
-       ThreadStartInfo *start_info = arg;
-       void *t_arg = start_info->arg;
-       int post_result;
-       LPTHREAD_START_ROUTINE start_func = start_info->start_routine;
-       DWORD result;
-       gboolean suspend = start_info->suspend;
-       HANDLE suspend_event = start_info->suspend_event;
-       MonoThreadInfo *info;
-
-       info = mono_thread_info_attach (&result);
-       info->runtime_thread = TRUE;
-       info->create_suspended = suspend;
-
-       mono_threads_platform_set_priority(info, start_info->priority);
-
-       mono_coop_sem_post (&(start_info->registered));
-
-       if (suspend) {
-               WaitForSingleObject (suspend_event, INFINITE); /* caller will suspend the thread before setting the event. */
-               CloseHandle (suspend_event);
-       }
+       HANDLE thread_handle;
 
-       result = start_func (t_arg);
+       thread_handle = GetCurrentThread ();
+       g_assert (thread_handle);
 
-       mono_thread_info_detach ();
+       /* The handle returned by GetCurrentThread () is a pseudo handle, so it can't
+        * be used to refer to the thread from other threads for things like aborting. */
+       DuplicateHandle (GetCurrentProcess (), thread_handle, GetCurrentProcess (), &thread_handle, THREAD_ALL_ACCESS, TRUE, 0);
 
-       return result;
+       g_assert (!info->handle);
+       info->handle = thread_handle;
 }
 
-HANDLE
-mono_threads_platform_create_thread (MonoThreadStart start_routine, gpointer arg, MonoThreadParm *tp, MonoNativeThreadId *out_tid)
+int
+mono_threads_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_data, gsize stack_size, MonoNativeThreadId *out_tid)
 {
-       ThreadStartInfo *start_info;
        HANDLE result;
        DWORD thread_id;
-       guint32 creation_flags = tp->creation_flags;
-       int res;
-
-       start_info = g_malloc0 (sizeof (ThreadStartInfo));
-       if (!start_info)
-               return NULL;
-       mono_coop_sem_init (&(start_info->registered), 0);
-       start_info->arg = arg;
-       start_info->priority = tp->priority;
-       start_info->start_routine = start_routine;
-       start_info->suspend = creation_flags & CREATE_SUSPENDED;
-       creation_flags &= ~CREATE_SUSPENDED;
-       if (start_info->suspend) {
-               start_info->suspend_event = CreateEvent (NULL, TRUE, FALSE, NULL);
-               if (!start_info->suspend_event)
-                       return NULL;
-       }
 
-       result = CreateThread (NULL, tp->stack_size, inner_start_thread, start_info, creation_flags, &thread_id);
-       if (result) {
-               res = mono_coop_sem_wait (&(start_info->registered), MONO_SEM_FLAGS_NONE);
-               g_assert (res != -1);
+       result = CreateThread (NULL, stack_size, (LPTHREAD_START_ROUTINE) thread_fn, thread_data, 0, &thread_id);
+       if (!result)
+               return -1;
+
+       /* A new handle is open when attaching
+        * the thread, so we don't need this one */
+       CloseHandle (result);
 
-               if (start_info->suspend) {
-                       g_assert (SuspendThread (result) != (DWORD)-1);
-                       SetEvent (start_info->suspend_event);
-               }
-       } else if (start_info->suspend) {
-               CloseHandle (start_info->suspend_event);
-       }
        if (out_tid)
                *out_tid = thread_id;
-       mono_coop_sem_destroy (&(start_info->registered));
-       g_free (start_info);
-       return result;
+
+       return 0;
 }
 
 
@@ -237,17 +187,6 @@ mono_native_thread_create (MonoNativeThreadId *tid, gpointer func, gpointer arg)
        return CreateThread (NULL, 0, (func), (arg), 0, (tid)) != NULL;
 }
 
-void
-mono_threads_platform_resume_created (MonoThreadInfo *info, MonoNativeThreadId tid)
-{
-       HANDLE handle;
-
-       handle = OpenThread (THREAD_ALL_ACCESS, TRUE, tid);
-       g_assert (handle);
-       ResumeThread (handle);
-       CloseHandle (handle);
-}
-
 #if HAVE_DECL___READFSDWORD==0
 static MONO_ALWAYS_INLINE unsigned long long
 __readfsdword (unsigned long offset)
@@ -297,30 +236,14 @@ mono_threads_platform_yield (void)
 void
 mono_threads_platform_exit (int exit_code)
 {
+       mono_thread_info_detach ();
        ExitThread (exit_code);
 }
 
 void
 mono_threads_platform_unregister (MonoThreadInfo *info)
 {
-}
-
-HANDLE
-mono_threads_platform_open_handle (void)
-{
-       HANDLE thread_handle;
-
-       thread_handle = GetCurrentThread ();
-       g_assert (thread_handle);
-
-       /*
-        * The handle returned by GetCurrentThread () is a pseudo handle, so it can't be used to
-        * refer to the thread from other threads for things like aborting.
-        */
-       DuplicateHandle (GetCurrentProcess (), thread_handle, GetCurrentProcess (), &thread_handle,
-                                        THREAD_ALL_ACCESS, TRUE, 0);
-
-       return thread_handle;
+       mono_threads_platform_set_exited (info);
 }
 
 int
@@ -336,6 +259,12 @@ mono_threads_platform_open_thread_handle (HANDLE handle, MonoNativeThreadId tid)
        return OpenThread (THREAD_ALL_ACCESS, TRUE, tid);
 }
 
+void
+mono_threads_platform_close_thread_handle (HANDLE handle)
+{
+       CloseHandle (handle);
+}
+
 #if defined(_MSC_VER)
 const DWORD MS_VC_EXCEPTION=0x406D1388;
 #pragma pack(push,8)
@@ -371,6 +300,10 @@ mono_native_thread_set_name (MonoNativeThreadId tid, const char *name)
 void
 mono_threads_platform_set_exited (MonoThreadInfo *info)
 {
+       g_assert (info->handle);
+       // No need to call CloseHandle() here since the InternalThread
+       // destructor will close the handle when the finalizer thread calls it
+       info->handle = NULL;
 }
 
 void
@@ -398,11 +331,16 @@ mono_threads_platform_get_priority (MonoThreadInfo *info)
        return GetThreadPriority (info->handle) + 2;
 }
 
-gboolean
+void
 mono_threads_platform_set_priority (MonoThreadInfo *info, MonoThreadPriority priority)
 {
+       BOOL res;
+
        g_assert (info->handle);
-       return SetThreadPriority (info->handle, priority - 2);
+
+       res = SetThreadPriority (info->handle, priority - 2);
+       if (!res)
+               g_error ("%s: SetThreadPriority failed, error %d", __func__, GetLastError ());
 }
 
 void
index 33796525b90bec8fca74b00d013382cf4eec6398..22eea19051cb75bd82a0003e0d0214a9dd406d06 100644 (file)
@@ -279,9 +279,9 @@ If return non null Hazard Pointer 1 holds the return value.
 MonoThreadInfo*
 mono_thread_info_lookup (MonoNativeThreadId id)
 {
-               MonoThreadHazardPointers *hp = mono_hazard_pointer_get ();
+       MonoThreadHazardPointers *hp = mono_hazard_pointer_get ();
 
-       if (!mono_lls_find (&thread_list, hp, (uintptr_t)id, HAZARD_FREE_ASYNC_CTX)) {
+       if (!mono_lls_find (&thread_list, hp, (uintptr_t)id)) {
                mono_hazard_pointer_clear_all (hp, -1);
                return NULL;
        } 
@@ -295,7 +295,7 @@ mono_thread_info_insert (MonoThreadInfo *info)
 {
        MonoThreadHazardPointers *hp = mono_hazard_pointer_get ();
 
-       if (!mono_lls_insert (&thread_list, hp, (MonoLinkedListSetNode*)info, HAZARD_FREE_SAFE_CTX)) {
+       if (!mono_lls_insert (&thread_list, hp, (MonoLinkedListSetNode*)info)) {
                mono_hazard_pointer_clear_all (hp, -1);
                return FALSE;
        } 
@@ -311,7 +311,7 @@ mono_thread_info_remove (MonoThreadInfo *info)
        gboolean res;
 
        THREADS_DEBUG ("removing info %p\n", info);
-       res = mono_lls_remove (&thread_list, hp, (MonoLinkedListSetNode*)info, HAZARD_FREE_SAFE_CTX);
+       res = mono_lls_remove (&thread_list, hp, (MonoLinkedListSetNode*)info);
        mono_hazard_pointer_clear_all (hp, -1);
        return res;
 }
@@ -373,6 +373,7 @@ register_thread (MonoThreadInfo *info, gpointer baseptr)
 
        info->stackdata = g_byte_array_new ();
 
+       mono_threads_platform_register (info);
        mono_threads_suspend_register (info);
 
        /*
@@ -690,7 +691,7 @@ mono_threads_init (MonoThreadInfoCallbacks *callbacks, size_t info_size)
        mono_os_sem_init (&global_suspend_semaphore, 1);
        mono_os_sem_init (&suspend_semaphore, 0);
 
-       mono_lls_init (&thread_list, NULL, HAZARD_FREE_NO_LOCK);
+       mono_lls_init (&thread_list, NULL);
        mono_thread_smr_init ();
        mono_threads_platform_init ();
        mono_threads_suspend_init ();
@@ -765,13 +766,6 @@ static gboolean
 mono_thread_info_core_resume (MonoThreadInfo *info)
 {
        gboolean res = FALSE;
-       if (info->create_suspended) {
-               MonoNativeThreadId tid = mono_thread_info_get_tid (info);
-               /* Have to special case this, as the normal suspend/resume pair are racy, they don't work if he resume is received before the suspend */
-               info->create_suspended = FALSE;
-               mono_threads_platform_resume_created (info, tid);
-               return TRUE;
-       }
 
        switch (mono_threads_transition_request_resume (info)) {
        case ResumeError:
@@ -1138,6 +1132,59 @@ mono_thread_info_is_async_context (void)
                return FALSE;
 }
 
+typedef struct {
+       gint32 ref;
+       MonoThreadStart start_routine;
+       gpointer start_routine_arg;
+       gint32 priority;
+       MonoCoopSem registered;
+       MonoThreadInfo *info;
+} CreateThreadData;
+
+static gsize WINAPI
+inner_start_thread (gpointer data)
+{
+       CreateThreadData *thread_data;
+       MonoThreadInfo *info;
+       MonoThreadStart start_routine;
+       gpointer start_routine_arg;
+       guint32 start_routine_res;
+       gint32 priority;
+       gsize dummy;
+
+       thread_data = (CreateThreadData*) data;
+       g_assert (thread_data);
+
+       start_routine = thread_data->start_routine;
+       start_routine_arg = thread_data->start_routine_arg;
+
+       priority = thread_data->priority;
+
+       info = mono_thread_info_attach (&dummy);
+       info->runtime_thread = TRUE;
+
+       mono_threads_platform_set_priority (info, priority);
+
+       thread_data->info = info;
+
+       mono_coop_sem_post (&thread_data->registered);
+
+       if (InterlockedDecrement (&thread_data->ref) == 0) {
+               mono_coop_sem_destroy (&thread_data->registered);
+               g_free (thread_data);
+       }
+
+       /* thread_data is not valid anymore */
+       thread_data = NULL;
+
+       /* Run the actual main function of the thread */
+       start_routine_res = start_routine (start_routine_arg);
+
+       mono_threads_platform_exit (start_routine_res);
+
+       g_assert_not_reached ();
+}
+
 /*
  * mono_threads_create_thread:
  *
@@ -1147,7 +1194,42 @@ mono_thread_info_is_async_context (void)
 HANDLE
 mono_threads_create_thread (MonoThreadStart start, gpointer arg, MonoThreadParm *tp, MonoNativeThreadId *out_tid)
 {
-       return mono_threads_platform_create_thread (start, arg, tp, out_tid);
+       CreateThreadData *thread_data;
+       MonoThreadInfo *info;
+       gint res;
+       gpointer ret;
+
+       thread_data = g_new0 (CreateThreadData, 1);
+       thread_data->ref = 2;
+       thread_data->start_routine = start;
+       thread_data->start_routine_arg = arg;
+       thread_data->priority = tp->priority;
+       mono_coop_sem_init (&thread_data->registered, 0);
+
+       res = mono_threads_platform_create_thread (inner_start_thread, (gpointer) thread_data, tp->stack_size, out_tid);
+       if (res != 0) {
+               /* ref is not going to be decremented in inner_start_thread */
+               InterlockedDecrement (&thread_data->ref);
+               ret = NULL;
+               goto done;
+       }
+
+       res = mono_coop_sem_wait (&thread_data->registered, MONO_SEM_FLAGS_NONE);
+       g_assert (res == 0);
+
+       info = thread_data->info;
+       g_assert (info);
+
+       ret = info->handle;
+       g_assert (ret);
+
+done:
+       if (InterlockedDecrement (&thread_data->ref) == 0) {
+               mono_coop_sem_destroy (&thread_data->registered);
+               g_free (thread_data);
+       }
+
+       return ret;
 }
 
 /*
@@ -1351,19 +1433,6 @@ mono_thread_info_exit (void)
        mono_threads_platform_exit (0);
 }
 
-/*
- * mono_thread_info_open_handle:
- *
- *   Return a io-layer/win32 handle for the current thread.
- * The handle need to be closed by calling CloseHandle () when it is no
- * longer needed.
- */
-HANDLE
-mono_thread_info_open_handle (void)
-{
-       return mono_threads_platform_open_handle ();
-}
-
 /*
  * mono_threads_open_thread_handle:
  *
@@ -1377,6 +1446,12 @@ mono_threads_open_thread_handle (HANDLE handle, MonoNativeThreadId tid)
        return mono_threads_platform_open_thread_handle (handle, tid);
 }
 
+void
+mono_threads_close_thread_handle (HANDLE handle)
+{
+       return mono_threads_platform_close_thread_handle (handle);
+}
+
 #define INTERRUPT_STATE ((MonoThreadInfoInterruptToken*) (size_t) -1)
 
 struct _MonoThreadInfoInterruptToken {
@@ -1621,8 +1696,8 @@ mono_thread_info_get_priority (MonoThreadInfo *info)
        return mono_threads_platform_get_priority (info);
 }
 
-gboolean
+void
 mono_thread_info_set_priority (MonoThreadInfo *info, MonoThreadPriority priority)
 {
-       return mono_threads_platform_set_priority (info, priority);
+       mono_threads_platform_set_priority (info, priority);
 }
index 6e74ec9fb8aa0ef95f5dbabcb429cc35dd680f24..5aafac7d7c28cad1ff71a1500dc066f03e945766 100644 (file)
@@ -221,11 +221,6 @@ typedef struct {
         */
        gboolean is_async_context;
 
-       gboolean create_suspended;
-
-       /* Semaphore used to implement CREATE_SUSPENDED */
-       MonoCoopSem create_suspended_sem;
-
        /*
         * Values of TLS variables for this thread.
         * This can be used to obtain the values of TLS variable for threads
@@ -246,6 +241,12 @@ typedef struct {
 
        /* Stack mark for targets that explicitly require one */
        gpointer stack_mark;
+
+#if defined(_POSIX_VERSION) || defined(__native_client__)
+       /* This is the data that was stored in the w32 handle */
+       GPtrArray *owned_mutexes;
+       gint32 priority;
+#endif
 } MonoThreadInfo;
 
 typedef struct {
@@ -416,7 +417,7 @@ mono_thread_info_is_async_context (void);
 void
 mono_thread_info_get_stack_bounds (guint8 **staddr, size_t *stsize);
 
-gboolean
+MONO_API gboolean
 mono_thread_info_yield (void);
 
 gint
@@ -434,9 +435,6 @@ mono_thread_info_tls_set (THREAD_INFO_TYPE *info, MonoTlsKey key, gpointer value
 void
 mono_thread_info_exit (void);
 
-HANDLE
-mono_thread_info_open_handle (void);
-
 void
 mono_thread_info_set_exited (THREAD_INFO_TYPE *info);
 
@@ -476,6 +474,9 @@ mono_threads_get_max_stack_size (void);
 HANDLE
 mono_threads_open_thread_handle (HANDLE handle, MonoNativeThreadId tid);
 
+void
+mono_threads_close_thread_handle (HANDLE handle);
+
 MONO_API void
 mono_threads_attach_tools_thread (void);
 
@@ -536,20 +537,20 @@ void mono_threads_suspend_free (THREAD_INFO_TYPE *info);
 void mono_threads_suspend_abort_syscall (THREAD_INFO_TYPE *info);
 gboolean mono_threads_suspend_needs_abort_syscall (void);
 
-HANDLE mono_threads_platform_create_thread (MonoThreadStart start, gpointer arg, MonoThreadParm *, MonoNativeThreadId *out_tid);
-void mono_threads_platform_resume_created (THREAD_INFO_TYPE *info, MonoNativeThreadId tid);
+void mono_threads_platform_register (THREAD_INFO_TYPE *info);
+void mono_threads_platform_unregister (THREAD_INFO_TYPE *info);
+int mono_threads_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_data, gsize stack_size, MonoNativeThreadId *out_tid);
 void mono_threads_platform_get_stack_bounds (guint8 **staddr, size_t *stsize);
 gboolean mono_threads_platform_yield (void);
 void mono_threads_platform_exit (int exit_code);
-void mono_threads_platform_unregister (THREAD_INFO_TYPE *info);
-HANDLE mono_threads_platform_open_handle (void);
 HANDLE mono_threads_platform_open_thread_handle (HANDLE handle, MonoNativeThreadId tid);
+void mono_threads_platform_close_thread_handle (HANDLE handle);
 void mono_threads_platform_set_exited (THREAD_INFO_TYPE *info);
 void mono_threads_platform_describe (THREAD_INFO_TYPE *info, GString *text);
 void mono_threads_platform_own_mutex (THREAD_INFO_TYPE *info, gpointer mutex_handle);
 void mono_threads_platform_disown_mutex (THREAD_INFO_TYPE *info, gpointer mutex_handle);
 MonoThreadPriority mono_threads_platform_get_priority (THREAD_INFO_TYPE *info);
-gboolean mono_threads_platform_set_priority (THREAD_INFO_TYPE *info, MonoThreadPriority priority);
+void mono_threads_platform_set_priority (THREAD_INFO_TYPE *info, MonoThreadPriority priority);
 
 void mono_threads_coop_begin_global_suspend (void);
 void mono_threads_coop_end_global_suspend (void);
@@ -679,7 +680,7 @@ mono_thread_info_disown_mutex (THREAD_INFO_TYPE *info, gpointer mutex_handle);
 MonoThreadPriority
 mono_thread_info_get_priority (THREAD_INFO_TYPE *info);
 
-gboolean
+void
 mono_thread_info_set_priority (THREAD_INFO_TYPE *info, MonoThreadPriority priority);
 
 #endif /* __MONO_THREADS_H__ */
index 9b51b0f993e11db27af7babc1ae97e5979ed3e53..5fd01a3db23a1edd6ca2804ec731a61c409919bb 100644 (file)
@@ -47,6 +47,7 @@
 #include "mono-os-mutex.h"
 #include "mono-proclib.h"
 #include "mono-threads.h"
+#include "mono-time.h"
 
 #undef DEBUG_REFS
 
@@ -55,6 +56,8 @@
 /* must be a power of 2 */
 #define HANDLE_PER_SLOT        (256)
 
+#define INFINITE 0xFFFFFFFF
+
 typedef struct {
        MonoW32HandleType type;
        guint ref;
@@ -194,7 +197,7 @@ mono_w32handle_issignalled (gpointer handle)
        return handle_data->signalled;
 }
 
-int
+static int
 mono_w32handle_lock_signal_mutex (void)
 {
 #ifdef DEBUG
@@ -206,7 +209,7 @@ mono_w32handle_lock_signal_mutex (void)
        return 0;
 }
 
-int
+static int
 mono_w32handle_unlock_signal_mutex (void)
 {
 #ifdef DEBUG
@@ -290,6 +293,11 @@ mono_w32handle_unlock_handle (gpointer handle)
 void
 mono_w32handle_init (void)
 {
+       static gboolean initialized = FALSE;
+
+       if (initialized)
+               return;
+
        g_assert ((sizeof (handle_ops) / sizeof (handle_ops[0]))
                  == MONO_W32HANDLE_COUNT);
 
@@ -310,6 +318,8 @@ mono_w32handle_init (void)
 
        mono_os_cond_init (&global_signal_cond);
        mono_os_mutex_init (&global_signal_mutex);
+
+       initialized = TRUE;
 }
 
 static void mono_w32handle_unref_full (gpointer handle, gboolean ignore_private_busy_handles);
@@ -347,8 +357,6 @@ mono_w32handle_cleanup (void)
 static void mono_w32handle_init_handle (MonoW32HandleBase *handle,
                               MonoW32HandleType type, gpointer handle_specific)
 {
-       g_assert (!shutting_down);
-       
        handle->type = type;
        handle->signalled = FALSE;
        handle->ref = 1;
@@ -375,8 +383,6 @@ static guint32 mono_w32handle_new_internal (MonoW32HandleType type,
        static guint32 last = 0;
        gboolean retry = FALSE;
        
-       g_assert (!shutting_down);
-       
        /* A linear scan should be fast enough.  Start from the last
         * allocation, assuming that handles are allocated more often
         * than they're freed. Leave the space reserved for file
@@ -895,12 +901,10 @@ spin (guint32 ms)
        nanosleep (&sleepytime, NULL);
 }
 
-gboolean
-mono_w32handle_count_signalled_handles (guint32 numhandles, gpointer *handles,
-       gboolean waitall, guint32 *retcount, guint32 *lowest)
+static void
+mono_w32handle_lock_handles (gpointer *handles, gsize numhandles)
 {
-       guint32 count, i, iter=0;
-       gboolean ret;
+       guint32 i, iter=0;
        int thr_ret;
 
        /* Lock all the handles, with backoff */
@@ -945,45 +949,10 @@ again:
        }
 
        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Locked all handles", __func__);
-
-       count=0;
-       *lowest=numhandles;
-
-       for(i=0; i<numhandles; i++) {
-               gpointer handle = handles[i];
-
-               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Checking handle %p", __func__, handle);
-
-               if(((mono_w32handle_test_capabilities (handle, MONO_W32HANDLE_CAP_OWN)==TRUE) &&
-                   (mono_w32handle_ops_isowned (handle) == TRUE)) ||
-                  (mono_w32handle_issignalled (handle))) {
-                       count++;
-
-                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Handle %p signalled", __func__,
-                                  handle);
-                       if(*lowest>i) {
-                               *lowest=i;
-                       }
-               }
-       }
-
-       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: %d event handles signalled", __func__, count);
-
-       if ((waitall == TRUE && count == numhandles) ||
-           (waitall == FALSE && count > 0)) {
-               ret=TRUE;
-       } else {
-               ret=FALSE;
-       }
-
-       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Returning %d", __func__, ret);
-
-       *retcount=count;
-
-       return(ret);
 }
 
-void mono_w32handle_unlock_handles (guint32 numhandles, gpointer *handles)
+static void
+mono_w32handle_unlock_handles (gpointer *handles, gsize numhandles)
 {
        guint32 i;
        int thr_ret;
@@ -1048,7 +1017,7 @@ signal_global (gpointer unused)
        mono_os_mutex_unlock (&global_signal_mutex);
 }
 
-int
+static int
 mono_w32handle_timedwait_signal (guint32 timeout, gboolean poll, gboolean *alerted)
 {
        int res;
@@ -1097,7 +1066,7 @@ signal_handle_and_unref (gpointer handle)
        mono_w32handle_unref (handle);
 }
 
-int
+static int
 mono_w32handle_timedwait_signal_handle (gpointer handle, guint32 timeout, gboolean poll, gboolean *alerted)
 {
        MonoW32HandleBase *handle_data;
@@ -1162,4 +1131,388 @@ void mono_w32handle_dump (void)
        mono_os_mutex_unlock (&scan_mutex);
 }
 
+static gboolean
+own_if_signalled (gpointer handle)
+{
+       if (!mono_w32handle_issignalled (handle))
+               return FALSE;
+
+       mono_w32handle_ops_own (handle);
+       return TRUE;
+}
+
+static gboolean
+own_if_owned( gpointer handle)
+{
+       if (!mono_w32handle_ops_isowned (handle))
+               return FALSE;
+
+       mono_w32handle_ops_own (handle);
+       return TRUE;
+}
+
+MonoW32HandleWaitRet
+mono_w32handle_wait_one (gpointer handle, guint32 timeout, gboolean alertable)
+{
+       MonoW32HandleWaitRet ret;
+       gboolean alerted;
+       gint64 start;
+       gint thr_ret;
+
+       alerted = FALSE;
+
+       if (mono_w32handle_test_capabilities (handle, MONO_W32HANDLE_CAP_SPECIAL_WAIT)) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p has special wait",
+                       __func__, handle);
+
+               switch (mono_w32handle_ops_specialwait (handle, timeout, alertable ? &alerted : NULL)) {
+               case WAIT_OBJECT_0:
+                       ret = MONO_W32HANDLE_WAIT_RET_SUCCESS_0;
+                       break;
+               case WAIT_IO_COMPLETION:
+                       ret = MONO_W32HANDLE_WAIT_RET_ALERTED;
+                       break;
+               case WAIT_TIMEOUT:
+                       ret = MONO_W32HANDLE_WAIT_RET_TIMEOUT;
+                       break;
+               case WAIT_FAILED:
+                       ret = MONO_W32HANDLE_WAIT_RET_FAILED;
+                       break;
+               default:
+                       g_assert_not_reached ();
+               }
+
+               if (alerted)
+                       ret = MONO_W32HANDLE_WAIT_RET_ALERTED;
+
+               return ret;
+       }
+
+       if (!mono_w32handle_test_capabilities (handle, MONO_W32HANDLE_CAP_WAIT)) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p can't be waited for",
+                       __func__, handle);
+
+               return MONO_W32HANDLE_WAIT_RET_FAILED;
+       }
+
+       thr_ret = mono_w32handle_lock_handle (handle);
+       g_assert (thr_ret == 0);
+
+       if (mono_w32handle_test_capabilities (handle, MONO_W32HANDLE_CAP_OWN)) {
+               if (own_if_owned (handle)) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p already owned",
+                               __func__, handle);
+
+                       ret = MONO_W32HANDLE_WAIT_RET_SUCCESS_0;
+                       goto done;
+               }
+       }
+
+       if (timeout != INFINITE)
+               start = mono_msec_ticks ();
+
+       for (;;) {
+               gint waited;
+
+               if (own_if_signalled (handle)) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p signalled",
+                               __func__, handle);
+
+                       ret = MONO_W32HANDLE_WAIT_RET_SUCCESS_0;
+                       goto done;
+               }
+
+               mono_w32handle_ops_prewait (handle);
+
+               if (timeout == INFINITE) {
+                       waited = mono_w32handle_timedwait_signal_handle (handle, INFINITE, FALSE, alertable ? &alerted : NULL);
+               } else {
+                       gint64 elapsed;
+
+                       elapsed = mono_msec_ticks () - start;
+                       if (elapsed > timeout) {
+                               ret = MONO_W32HANDLE_WAIT_RET_TIMEOUT;
+                               goto done;
+                       }
+
+                       waited = mono_w32handle_timedwait_signal_handle (handle, timeout - elapsed, FALSE, alertable ? &alerted : NULL);
+               }
+
+               if (alerted) {
+                       ret = MONO_W32HANDLE_WAIT_RET_ALERTED;
+                       goto done;
+               }
+
+               if (waited != 0) {
+                       ret = MONO_W32HANDLE_WAIT_RET_TIMEOUT;
+                       goto done;
+               }
+       }
+
+done:
+       thr_ret = mono_w32handle_unlock_handle (handle);
+       g_assert (thr_ret == 0);
+
+       return ret;
+}
+
+MonoW32HandleWaitRet
+mono_w32handle_wait_multiple (gpointer *handles, gsize nhandles, gboolean waitall, guint32 timeout, gboolean alertable)
+{
+       MonoW32HandleWaitRet ret;
+       gboolean alerted, poll;
+       gint i, thr_ret;
+       gint64 start;
+       gpointer handles_sorted [MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS];
+
+       if (nhandles == 0)
+               return MONO_W32HANDLE_WAIT_RET_FAILED;
+
+       if (nhandles == 1)
+               return mono_w32handle_wait_one (handles [0], timeout, alertable);
+
+       alerted = FALSE;
+
+       if (nhandles > MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: too many handles: %d",
+                       __func__, nhandles);
+
+               return MONO_W32HANDLE_WAIT_RET_FAILED;
+       }
+
+       for (i = 0; i < nhandles; ++i) {
+               if (!mono_w32handle_test_capabilities (handles[i], MONO_W32HANDLE_CAP_WAIT)
+                        && !mono_w32handle_test_capabilities (handles[i], MONO_W32HANDLE_CAP_SPECIAL_WAIT))
+               {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p can't be waited for",
+                                  __func__, handles [i]);
+
+                       return MONO_W32HANDLE_WAIT_RET_FAILED;
+               }
+
+               handles_sorted [i] = handles [i];
+       }
+
+       qsort (handles_sorted, nhandles, sizeof (gpointer), g_direct_equal);
+       for (i = 1; i < nhandles; ++i) {
+               if (handles_sorted [i - 1] == handles_sorted [i]) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p is duplicated",
+                               __func__, handles_sorted [i]);
+
+                       return MONO_W32HANDLE_WAIT_RET_FAILED;
+               }
+       }
+
+       poll = FALSE;
+       for (i = 0; i < nhandles; ++i) {
+               if (mono_w32handle_get_type (handles [i]) == MONO_W32HANDLE_PROCESS) {
+                       /* Can't wait for a process handle + another handle without polling */
+                       poll = TRUE;
+               }
+       }
+
+       if (timeout != INFINITE)
+               start = mono_msec_ticks ();
+
+       for (i = 0; i < nhandles; ++i) {
+               /* Add a reference, as we need to ensure the handle wont
+                * disappear from under us while we're waiting in the loop
+                * (not lock, as we don't want exclusive access here) */
+               mono_w32handle_ref (handles [i]);
+       }
+
+       for (;;) {
+               gsize count, lowest;
+               gboolean signalled;
+               gint waited;
+
+               count = 0;
+               lowest = nhandles;
+
+               mono_w32handle_lock_handles (handles, nhandles);
+
+               for (i = 0; i < nhandles; i++) {
+                       if ((mono_w32handle_test_capabilities (handles [i], MONO_W32HANDLE_CAP_OWN) && mono_w32handle_ops_isowned (handles [i]))
+                                || mono_w32handle_issignalled (handles [i]))
+                       {
+                               count ++;
+
+                               if (i < lowest)
+                                       lowest = i;
+                       }
+               }
+
+               signalled = (waitall && count == nhandles) || (!waitall && count > 0);
+
+               if (signalled) {
+                       for (i = 0; i < nhandles; i++)
+                               own_if_signalled (handles [i]);
+               }
+
+               mono_w32handle_unlock_handles (handles, nhandles);
+
+               if (signalled) {
+                       ret = MONO_W32HANDLE_WAIT_RET_SUCCESS_0 + lowest;
+                       goto done;
+               }
+
+               for (i = 0; i < nhandles; i++) {
+                       mono_w32handle_ops_prewait (handles[i]);
+
+                       if (mono_w32handle_test_capabilities (handles [i], MONO_W32HANDLE_CAP_SPECIAL_WAIT)
+                                && !mono_w32handle_issignalled (handles [i]))
+                       {
+                               mono_w32handle_ops_specialwait (handles [i], 0, alertable ? &alerted : NULL);
+                       }
+               }
+
+               thr_ret = mono_w32handle_lock_signal_mutex ();
+               g_assert (thr_ret == 0);
+
+               if (waitall) {
+                       signalled = TRUE;
+                       for (i = 0; i < nhandles; ++i) {
+                               if (!mono_w32handle_issignalled (handles [i])) {
+                                       signalled = FALSE;
+                                       break;
+                               }
+                       }
+               } else {
+                       signalled = FALSE;
+                       for (i = 0; i < nhandles; ++i) {
+                               if (mono_w32handle_issignalled (handles [i])) {
+                                       signalled = TRUE;
+                                       break;
+                               }
+                       }
+               }
+
+               waited = 0;
+
+               if (!signalled) {
+                       if (timeout == INFINITE) {
+                               waited = mono_w32handle_timedwait_signal (INFINITE, poll, alertable ? &alerted : NULL);
+                       } else {
+                               gint64 elapsed;
+
+                               elapsed = mono_msec_ticks () - start;
+                               if (elapsed > timeout) {
+                                       ret = MONO_W32HANDLE_WAIT_RET_TIMEOUT;
+
+                                       thr_ret = mono_w32handle_unlock_signal_mutex ();
+                                       g_assert (thr_ret == 0);
+
+                                       goto done;
+                               }
+
+                               waited = mono_w32handle_timedwait_signal (timeout - elapsed, poll, alertable ? &alerted : NULL);
+                       }
+               }
+
+               thr_ret = mono_w32handle_unlock_signal_mutex ();
+               g_assert (thr_ret == 0);
+
+               if (alerted) {
+                       ret = MONO_W32HANDLE_WAIT_RET_ALERTED;
+                       goto done;
+               }
+
+               if (waited != 0) {
+                       ret = MONO_W32HANDLE_WAIT_RET_TIMEOUT;
+                       goto done;
+               }
+       }
+
+done:
+       for (i = 0; i < nhandles; i++) {
+               /* Unref everything we reffed above */
+               mono_w32handle_unref (handles [i]);
+       }
+
+       return ret;
+}
+
+MonoW32HandleWaitRet
+mono_w32handle_signal_and_wait (gpointer signal_handle, gpointer wait_handle, guint32 timeout, gboolean alertable)
+{
+       MonoW32HandleWaitRet ret;
+       gint64 start;
+       gboolean alerted;
+       gint thr_ret;
+
+       alerted = FALSE;
+
+       if (!mono_w32handle_test_capabilities (signal_handle, MONO_W32HANDLE_CAP_SIGNAL))
+               return MONO_W32HANDLE_WAIT_RET_FAILED;
+       if (!mono_w32handle_test_capabilities (wait_handle, MONO_W32HANDLE_CAP_WAIT))
+               return MONO_W32HANDLE_WAIT_RET_FAILED;
+
+       if (mono_w32handle_test_capabilities (wait_handle, MONO_W32HANDLE_CAP_SPECIAL_WAIT)) {
+               g_warning ("%s: handle %p has special wait, implement me!!", __func__, wait_handle);
+               return MONO_W32HANDLE_WAIT_RET_FAILED;
+       }
+
+       thr_ret = mono_w32handle_lock_handle (wait_handle);
+       g_assert (thr_ret == 0);
+
+       mono_w32handle_ops_signal (signal_handle);
+
+       if (mono_w32handle_test_capabilities (wait_handle, MONO_W32HANDLE_CAP_OWN)) {
+               if (own_if_owned (wait_handle)) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p already owned",
+                               __func__, wait_handle);
+
+                       ret = MONO_W32HANDLE_WAIT_RET_SUCCESS_0;
+                       goto done;
+               }
+       }
+
+       if (timeout != INFINITE)
+               start = mono_msec_ticks ();
+
+       for (;;) {
+               gint waited;
+
+               if (own_if_signalled (wait_handle)) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p signalled",
+                               __func__, wait_handle);
+
+                       ret = MONO_W32HANDLE_WAIT_RET_SUCCESS_0;
+                       goto done;
+               }
+
+               mono_w32handle_ops_prewait (wait_handle);
+
+               if (timeout == INFINITE) {
+                       waited = mono_w32handle_timedwait_signal_handle (wait_handle, INFINITE, FALSE, alertable ? &alerted : NULL);
+               } else {
+                       gint64 elapsed;
+
+                       elapsed = mono_msec_ticks () - start;
+                       if (elapsed > timeout) {
+                               ret = MONO_W32HANDLE_WAIT_RET_TIMEOUT;
+                               goto done;
+                       }
+
+                       waited = mono_w32handle_timedwait_signal_handle (wait_handle, timeout - elapsed, FALSE, alertable ? &alerted : NULL);
+               }
+
+               if (alerted) {
+                       ret = MONO_W32HANDLE_WAIT_RET_ALERTED;
+                       goto done;
+               }
+
+               if (waited != 0) {
+                       ret = MONO_W32HANDLE_WAIT_RET_TIMEOUT;
+                       goto done;
+               }
+       }
+
+done:
+       thr_ret = mono_w32handle_unlock_handle (wait_handle);
+       g_assert (thr_ret == 0);
+
+       return ret;
+}
+
 #endif /* !defined(HOST_WIN32) */
index 0ba409f1fd282341afe52e26dc04f49ec67a1792..27c403ce39dde47cb9563be14b0d5d58ecc5bdb0 100644 (file)
@@ -3,12 +3,13 @@
 #define _MONO_UTILS_W32HANDLE_H_
 
 #include <config.h>
-
-#if !defined(HOST_WIN32)
-
 #include <glib.h>
 
+#ifndef INVALID_HANDLE_VALUE
 #define INVALID_HANDLE_VALUE (gpointer)-1
+#endif
+
+#define MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS 64
 
 typedef enum {
        MONO_W32HANDLE_UNUSED = 0,
@@ -148,18 +149,6 @@ mono_w32handle_ops_typename (MonoW32HandleType type);
 gsize
 mono_w32handle_ops_typesize (MonoW32HandleType type);
 
-gboolean
-mono_w32handle_count_signalled_handles (guint32 numhandles, gpointer *handles, gboolean waitall, guint32 *retcount, guint32 *lowest);
-
-void
-mono_w32handle_unlock_handles (guint32 numhandles, gpointer *handles);
-
-int
-mono_w32handle_timedwait_signal_handle (gpointer handle, guint32 timeout, gboolean poll, gboolean *alerted);
-
-int
-mono_w32handle_timedwait_signal (guint32 timeout, gboolean poll, gboolean *alerted);
-
 void
 mono_w32handle_set_signal_state (gpointer handle, gboolean state, gboolean broadcast);
 
@@ -175,12 +164,20 @@ mono_w32handle_trylock_handle (gpointer handle);
 int
 mono_w32handle_unlock_handle (gpointer handle);
 
-int
-mono_w32handle_lock_signal_mutex (void);
+typedef enum {
+       MONO_W32HANDLE_WAIT_RET_SUCCESS_0 =  0,
+       MONO_W32HANDLE_WAIT_RET_ALERTED   = -1,
+       MONO_W32HANDLE_WAIT_RET_TIMEOUT   = -2,
+       MONO_W32HANDLE_WAIT_RET_FAILED    = -3,
+} MonoW32HandleWaitRet;
 
-int
-mono_w32handle_unlock_signal_mutex (void);
+MonoW32HandleWaitRet
+mono_w32handle_wait_one (gpointer handle, guint32 timeout, gboolean alertable);
+
+MonoW32HandleWaitRet
+mono_w32handle_wait_multiple (gpointer *handles, gsize nhandles, gboolean waitall, guint32 timeout, gboolean alertable);
 
-#endif /* !defined(HOST_WIN32) */
+MonoW32HandleWaitRet
+mono_w32handle_signal_and_wait (gpointer signal_handle, gpointer wait_handle, guint32 timeout, gboolean alertable);
 
 #endif /* _MONO_UTILS_W32HANDLE_H_ */
index 52dd0baad9a24d0fbc87a2b336decb51bbe8216f..e0979dbbee07d46d915e1984a3d051cd16c388da 100644 (file)
@@ -20,7 +20,6 @@
   </ItemGroup>\r
   <ItemGroup>\r
     <ClCompile Include="..\mono\sgen\sgen-alloc.c" />\r
-    <ClCompile Include="..\mono\metadata\sgen-bridge.c" />\r
     <ClCompile Include="..\mono\sgen\sgen-array-list.c" />\r
     <ClCompile Include="..\mono\sgen\sgen-cardtable.c" />\r
     <ClCompile Include="..\mono\sgen\sgen-debug.c" />\r
index d40313b932436adff6a28bcfcf9f1a0623144223..b1c22545a6c7bdff143e26a4f54bf490bd33d539 100644 (file)
@@ -4,9 +4,6 @@
     <ClCompile Include="..\mono\sgen\sgen-alloc.c">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\mono\metadata\sgen-bridge.c">\r
-      <Filter>Source Files</Filter>\r
-    </ClCompile>\r
     <ClCompile Include="..\mono\sgen\sgen-cardtable.c">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
index 66283179cfe3af2b78a5e7cbc167cef82b817279..5d638f1b8fb83ca27fd2e0ea78b5c61c346f91f7 100644 (file)
@@ -19,7 +19,6 @@
     </ProjectConfiguration>\r
   </ItemGroup>\r
   <ItemGroup>\r
-    <ClCompile Include="..\mono\metadata\remoting.c" />\r
     <ClCompile Include="..\mono\mini\alias-analysis.c" />\r
     <ClCompile Include="..\mono\mini\arch-stubs.c" />\r
     <ClCompile Include="..\mono\mini\exceptions-amd64.c">\r
index 75748b858bebbf78297ef860fe58601862bad323..35641c0e6af5d06deb99314d48f855f80a571cc8 100644 (file)
     <ClCompile Include="..\mono\mini\mini-x86.c">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\mono\metadata\remoting.c">\r
-      <Filter>Source Files</Filter>\r
-    </ClCompile>\r
     <ClCompile Include="..\mono\mini\seq-points.c">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
index 3acce45d4bbc5356b29c7993c7e5c5bef8f58108..82eff3379b65384685a22c13a1ffa58426c62d70 100644 (file)
       <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>eglib.lib;libmonoutils.lib;libmonoruntime$(MONO_TARGET_SUFFIX).lib;libmono-static$(MONO_TARGET_SUFFIX).lib;$(GC_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>eglib.lib;$(MONO_STATIC_LIBMONO_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <ModuleDefinitionFile>$(MONO_DEF)</ModuleDefinitionFile>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>eglib.lib;libmonoutils.lib;libmonoruntime$(MONO_TARGET_SUFFIX).lib;libmono-static$(MONO_TARGET_SUFFIX).lib;$(GC_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>eglib.lib;$(MONO_STATIC_LIBMONO_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <ModuleDefinitionFile>$(MONO_DEF)</ModuleDefinitionFile>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>eglib.lib;libmonoutils.lib;libmonoruntime$(MONO_TARGET_SUFFIX).lib;libmono-static$(MONO_TARGET_SUFFIX).lib;$(GC_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>eglib.lib;$(MONO_STATIC_LIBMONO_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <ModuleDefinitionFile>$(MONO_DEF)</ModuleDefinitionFile>\r
       <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
       <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>eglib.lib;libmonoutils.lib;libmonoruntime$(MONO_TARGET_SUFFIX).lib;libmono-static$(MONO_TARGET_SUFFIX).lib;$(GC_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>eglib.lib;$(MONO_STATIC_LIBMONO_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <ModuleDefinitionFile>$(MONO_DEF)</ModuleDefinitionFile>\r
       <ImportLibrary>$(MONO_BUILD_DIR_PREFIX)$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
       <Project>{8fc2b0c8-51ad-49df-851f-5d01a77a75e4}</Project>\r
     </ProjectReference>\r
   </ItemGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="..\mono\mini\mini-windows-dllmain.c" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <None Include="mono.def" />\r
+  </ItemGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
   <ImportGroup Label="ExtensionTargets">\r
   </ImportGroup>\r
index 0d407ea4f940edc25a0d364ff323a36f41c96cb9..91861b6cc1dc725ce34082e0fd3feaa8aea7d309 100644 (file)
       <UniqueIdentifier>{5370c3c4-b6ec-4f8a-8b21-ce4e782720a6}</UniqueIdentifier>\r
     </Filter>\r
   </ItemGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="..\mono\mini\mini-windows-dllmain.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <None Include="mono.def">\r
+      <Filter>Resource Files</Filter>\r
+    </None>\r
+  </ItemGroup>\r
 </Project>
\ No newline at end of file
index d0c79d0f0a4e2d66cd6335238edaae8736756357..41f6439154b8065c50523f175f48f0c55c97835b 100644 (file)
     <ClCompile Include="..\mono\metadata\cominterop.c" />\r
     <ClCompile Include="..\mono\metadata\console-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
     <ClCompile Include="..\mono\metadata\debug-mono-ppdb.c" />\r
     <ClCompile Include="..\mono\metadata\debug-mono-symfile.c" />\r
     <ClCompile Include="..\mono\metadata\decimal-ms.c" />\r
+    <ClCompile Include="..\mono\metadata\dynamic-image.c" />\r
+    <ClCompile Include="..\mono\metadata\dynamic-stream.c" />\r
     <ClCompile Include="..\mono\metadata\domain.c" />\r
     <ClCompile Include="..\mono\metadata\environment.c" />\r
     <ClCompile Include="..\mono\metadata\exception.c" />\r
@@ -77,6 +80,7 @@
     <ClCompile Include="..\mono\metadata\mono-security.c" />\r
     <ClCompile Include="..\mono\metadata\seq-points-data.c" />\r
     <ClCompile Include="..\mono\metadata\sgen-mono.c" />\r
+    <ClCompile Include="..\mono\metadata\sgen-os-coop.c" />\r
     <ClCompile Include="..\mono\metadata\threadpool-ms-io.c" />\r
     <ClCompile Include="..\mono\metadata\threadpool-ms.c" />\r
     <ClCompile Include="..\mono\metadata\sgen-bridge.c" />\r
     <ClCompile Include="..\mono\metadata\sgen-toggleref.c" />\r
     <ClCompile Include="..\mono\metadata\sgen-stw.c" />\r
     <ClCompile Include="..\mono\metadata\socket-io.c" />\r
+    <ClCompile Include="..\mono\metadata\sre.c" />\r
+    <ClCompile Include="..\mono\metadata\sre-encode.c" />\r
+    <ClCompile Include="..\mono\metadata\sre-save.c" />\r
     <ClCompile Include="..\mono\metadata\string-icalls.c" />\r
     <ClCompile Include="..\mono\metadata\sysmath.c" />\r
     <ClCompile Include="..\mono\metadata\threads.c" />\r
     <ClInclude Include="..\mono\metadata\coree.h" />\r
     <ClInclude Include="..\mono\metadata\culture-info-tables.h" />\r
     <ClInclude Include="..\mono\metadata\culture-info.h" />\r
+    <ClInclude Include="..\mono\metadata\custom-attrs-internals.h" />\r
     <ClInclude Include="..\mono\metadata\debug-helpers.h" />\r
     <ClInclude Include="..\mono\metadata\debug-mono-ppdb.h" />\r
     <ClInclude Include="..\mono\metadata\debug-mono-symfile.h" />\r
     <ClInclude Include="..\mono\metadata\domain-internals.h" />\r
+    <ClInclude Include="..\mono\metadata\dynamic-image-internals.h" />\r
+    <ClInclude Include="..\mono\metadata\dynamic-stream-internals.h" />\r
     <ClInclude Include="..\mono\metadata\environment.h" />\r
     <ClInclude Include="..\mono\metadata\exception.h" />\r
     <ClInclude Include="..\mono\metadata\file-io.h" />\r
     <ClInclude Include="..\mono\metadata\profiler.h" />\r
     <ClInclude Include="..\mono\metadata\rand.h" />\r
     <ClInclude Include="..\mono\metadata\reflection.h" />\r
+    <ClInclude Include="..\mono\metadata\reflection-cache.h" />\r
+    <ClInclude Include="..\mono\metadata\reflection-internals.h" />\r
     <ClInclude Include="..\mono\metadata\runtime.h" />\r
     <ClInclude Include="..\mono\metadata\security-core-clr.h" />\r
     <ClInclude Include="..\mono\metadata\security-manager.h" />\r
     <ClInclude Include="..\mono\metadata\sgen-bridge.h" />\r
     <ClInclude Include="..\mono\metadata\sgen-toggleref.h" />\r
     <ClInclude Include="..\mono\metadata\socket-io.h" />\r
+    <ClInclude Include="..\mono\metadata\sre-internals.h" />\r
     <ClInclude Include="..\mono\metadata\string-icalls.h" />\r
     <ClInclude Include="..\mono\metadata\sysmath.h" />\r
     <ClInclude Include="..\mono\metadata\tabledefs.h" />\r
index e7d4b4110f5afa7abcbf9ed4fa9876ae1a803193..13f50fb2be4cdd5171a246f051f07b3b60db1da9 100644 (file)
     <ClCompile Include="..\mono\metadata\metadata-cross-helpers.c">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\mono\metadata\custom-attrs.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\mono\metadata\dynamic-image.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\mono\metadata\dynamic-stream.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\mono\metadata\sre.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\mono\metadata\sre-encode.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\mono\metadata\sre-save.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\mono\metadata\sgen-os-coop.c">\r
+      <Filter>Source Files\sgen</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClInclude Include="..\mono\metadata\appdomain.h">\r
     <ClInclude Include="..\mono\metadata\gc-internals.h">\r
       <Filter>Header Files\gc</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\mono\metadata\custom-attrs-internals.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\mono\metadata\dynamic-image-internals.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\mono\metadata\dynamic-stream-internals.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\mono\metadata\reflection-cache.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\mono\metadata\reflection-internals.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\mono\metadata\sre-internals.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <Filter Include="Header Files">\r
index 7924eca87c70ac643909afeacd1be89af8edd28d..1ccf4e7563988b27dba1d570fb851b2f6e0cca4e 100644 (file)
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
     <ConfigurationType>Utility</ConfigurationType>\r
     <UseDebugLibraries>true</UseDebugLibraries>\r
-    <CharacterSet>MultiByte</CharacterSet>\r
+    <CharacterSet>Unicode</CharacterSet>\r
     <PlatformToolset>v140</PlatformToolset>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
     <ConfigurationType>Utility</ConfigurationType>\r
     <UseDebugLibraries>false</UseDebugLibraries>\r
     <WholeProgramOptimization>true</WholeProgramOptimization>\r
-    <CharacterSet>MultiByte</CharacterSet>\r
+    <CharacterSet>Unicode</CharacterSet>\r
     <PlatformToolset>v140</PlatformToolset>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">\r
     <ConfigurationType>Utility</ConfigurationType>\r
     <UseDebugLibraries>true</UseDebugLibraries>\r
-    <CharacterSet>MultiByte</CharacterSet>\r
+    <CharacterSet>Unicode</CharacterSet>\r
     <PlatformToolset>v140</PlatformToolset>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">\r
     <ConfigurationType>Utility</ConfigurationType>\r
     <UseDebugLibraries>false</UseDebugLibraries>\r
     <WholeProgramOptimization>true</WholeProgramOptimization>\r
-    <CharacterSet>MultiByte</CharacterSet>\r
+    <CharacterSet>Unicode</CharacterSet>\r
     <PlatformToolset>v140</PlatformToolset>\r
   </PropertyGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
index bcf3cc3e6cb58d2179a41a11e9c327ce26b7f82d..e16fcf235fcbe54c6e690dc3ffd850bf3e3baf01 100644 (file)
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
     <ConfigurationType>Utility</ConfigurationType>\r
     <UseDebugLibraries>true</UseDebugLibraries>\r
-    <CharacterSet>MultiByte</CharacterSet>\r
+    <CharacterSet>Unicode</CharacterSet>\r
     <PlatformToolset>v140</PlatformToolset>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
     <ConfigurationType>Utility</ConfigurationType>\r
     <UseDebugLibraries>false</UseDebugLibraries>\r
     <WholeProgramOptimization>true</WholeProgramOptimization>\r
-    <CharacterSet>MultiByte</CharacterSet>\r
+    <CharacterSet>Unicode</CharacterSet>\r
     <PlatformToolset>v140</PlatformToolset>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">\r
     <ConfigurationType>Utility</ConfigurationType>\r
     <UseDebugLibraries>true</UseDebugLibraries>\r
-    <CharacterSet>MultiByte</CharacterSet>\r
+    <CharacterSet>Unicode</CharacterSet>\r
     <PlatformToolset>v140</PlatformToolset>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">\r
     <ConfigurationType>Utility</ConfigurationType>\r
     <UseDebugLibraries>false</UseDebugLibraries>\r
     <WholeProgramOptimization>true</WholeProgramOptimization>\r
-    <CharacterSet>MultiByte</CharacterSet>\r
+    <CharacterSet>Unicode</CharacterSet>\r
     <PlatformToolset>v140</PlatformToolset>\r
   </PropertyGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
@@ -81,7 +81,7 @@
   </ImportGroup>\r
   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
-       <Import Project="mono.props" />\r
+    <Import Project="mono.props" />\r
     <Import Project="mono-test.props" />\r
     <Import Project="mono-test-x64.props" />\r
     <Import Project="mono-full-aot-test.props" />\r
index 8d8537e24670b6562d9d31932dbce6a9c6df7edd..3b853a182a33f7024325520b5fc5c76e4b4ad7d3 100644 (file)
     <ConfigurationType>Utility</ConfigurationType>\r
     <UseDebugLibraries>true</UseDebugLibraries>\r
     <PlatformToolset>v140</PlatformToolset>\r
-    <CharacterSet>MultiByte</CharacterSet>\r
+    <CharacterSet>Unicode</CharacterSet>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
     <ConfigurationType>Utility</ConfigurationType>\r
     <UseDebugLibraries>false</UseDebugLibraries>\r
     <PlatformToolset>v140</PlatformToolset>\r
     <WholeProgramOptimization>true</WholeProgramOptimization>\r
-    <CharacterSet>MultiByte</CharacterSet>\r
+    <CharacterSet>Unicode</CharacterSet>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">\r
     <ConfigurationType>Utility</ConfigurationType>\r
     <UseDebugLibraries>true</UseDebugLibraries>\r
     <PlatformToolset>v140</PlatformToolset>\r
-    <CharacterSet>MultiByte</CharacterSet>\r
+    <CharacterSet>Unicode</CharacterSet>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">\r
     <ConfigurationType>Utility</ConfigurationType>\r
     <UseDebugLibraries>false</UseDebugLibraries>\r
     <PlatformToolset>v140</PlatformToolset>\r
     <WholeProgramOptimization>true</WholeProgramOptimization>\r
-    <CharacterSet>MultiByte</CharacterSet>\r
+    <CharacterSet>Unicode</CharacterSet>\r
   </PropertyGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
   <ImportGroup Label="ExtensionSettings">\r
diff --git a/msvc/mono-nunit-test.props b/msvc/mono-nunit-test.props
new file mode 100644 (file)
index 0000000..5c3c2b7
--- /dev/null
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Label="UserMacros">
+    <MONO_NUNIT_TEST_DIR>$(MONO_DIR)/mcs/class/System</MONO_NUNIT_TEST_DIR>
+    <MONO_NUNIT_TARGET>$(MONO_DIR)/mcs/class/lib/net_4_x/nunit-console.exe</MONO_NUNIT_TARGET>
+    <MONO_PATH>$(MONO_PATH);$(MONO_NUNIT_TEST_DIR)</MONO_PATH>
+    <MONO_CFG_DIR>$(MONO_DIR)/runtime/etc</MONO_CFG_DIR>
+    <MONO_NUNIT_RUN_TARGET>net_4_x_System_test.dll</MONO_NUNIT_RUN_TARGET>
+    <MONO_NUNIT_FIXTURE></MONO_NUNIT_FIXTURE>
+    <MONO_NUNIT_ARGS>-noshadow -exclude=NotWorking,ValueAdd,CAS,InetAccess /labels</MONO_NUNIT_ARGS>
+    <MONO_NUNIT_ARGS Condition="'$(MONO_NUNIT_FIXTURE)'!=''">$(MONO_NUNIT_ARGS) -fixture $(MONO_NUNIT_FIXTURE)</MONO_NUNIT_ARGS>
+    <MONO_NUNIT_RUN_ADDITIONAL_ARGS>
+    </MONO_NUNIT_RUN_ADDITIONAL_ARGS>
+    <MONO_NUNIT_RUN_ARGS>"$(MONO_NUNIT_TARGET)" "$(MONO_NUNIT_RUN_TARGET)" $(MONO_NUNIT_ARGS) $(MONO_NUNIT_RUN_ADDITIONAL_ARGS)</MONO_NUNIT_RUN_ARGS>
+  </PropertyGroup>
+  <ItemGroup>
+    <BuildMacro Include="MONO_NUNIT_TEST_DIR">
+      <Value>$(MONO_NUNIT_TEST_DIR)</Value>
+    </BuildMacro>
+    <BuildMacro Include="MONO_NUNIT_TARGET">
+      <Value>$(MONO_NUNIT_TARGET)</Value>
+    </BuildMacro>
+    <BuildMacro Include="MONO_PATH">
+      <Value>$(MONO_PATH)</Value>
+    </BuildMacro>
+    <BuildMacro Include="MONO_CFG_DIR">
+      <Value>$(MONO_CFG_DIR)</Value>
+    </BuildMacro>
+    <BuildMacro Include="MONO_NUNIT_RUN_TARGET">
+      <Value>$(MONO_NUNIT_RUN_TARGET)</Value>
+    </BuildMacro>
+    <BuildMacro Include="MONO_NUNIT_FIXTURE">
+      <Value>$(MONO_NUNIT_FIXTURE)</Value>
+    </BuildMacro>
+    <BuildMacro Include="MONO_NUNIT_ARGS">
+      <Value>$(MONO_NUNIT_ARGS)</Value>
+    </BuildMacro>
+    <BuildMacro Include="MONO_NUNIT_RUN_ADDITIONAL_ARGS">
+      <Value>$(MONO_NUNIT_RUN_ADDITIONAL_ARGS)</Value>
+    </BuildMacro>
+    <BuildMacro Include="MONO_NUNIT_RUN_ARGS">
+      <Value>$(MONO_NUNIT_RUN_ARGS)</Value>
+    </BuildMacro>
+  </ItemGroup>
+  <ItemDefinitionGroup />
+</Project>
\ No newline at end of file
diff --git a/msvc/mono-nunit-test.vcxproj b/msvc/mono-nunit-test.vcxproj
new file mode 100644 (file)
index 0000000..0e9d6f8
--- /dev/null
@@ -0,0 +1,224 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup Label="ProjectConfigurations">\r
+    <ProjectConfiguration Include="Debug|Win32">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Win32">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug|x64">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|x64">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ProjectReference Include="mono.vcxproj">\r
+      <Project>{a0eddcd9-940f-432c-a28f-7ef322437d79}</Project>\r
+    </ProjectReference>\r
+  </ItemGroup>\r
+  <PropertyGroup Label="Globals">\r
+    <ProjectGuid>{0046B994-40A8-4C64-AC9D-429DC9177B54}</ProjectGuid>\r
+    <Keyword>Win32Proj</Keyword>\r
+    <RootNamespace>mononunittest</RootNamespace>\r
+    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
+    <ConfigurationType>Utility</ConfigurationType>\r
+    <UseDebugLibraries>true</UseDebugLibraries>\r
+    <PlatformToolset>v140</PlatformToolset>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
+    <ConfigurationType>Utility</ConfigurationType>\r
+    <UseDebugLibraries>false</UseDebugLibraries>\r
+    <PlatformToolset>v140</PlatformToolset>\r
+    <WholeProgramOptimization>true</WholeProgramOptimization>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">\r
+    <ConfigurationType>Utility</ConfigurationType>\r
+    <UseDebugLibraries>true</UseDebugLibraries>\r
+    <PlatformToolset>v140</PlatformToolset>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">\r
+    <ConfigurationType>Utility</ConfigurationType>\r
+    <UseDebugLibraries>false</UseDebugLibraries>\r
+    <PlatformToolset>v140</PlatformToolset>\r
+    <WholeProgramOptimization>true</WholeProgramOptimization>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
+  <ImportGroup Label="ExtensionSettings">\r
+  </ImportGroup>\r
+  <ImportGroup Label="Shared">\r
+  </ImportGroup>\r
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="mono.props" />\r
+    <Import Project="mono-test.props" />\r
+    <Import Project="mono-test-Win32.props" />\r
+    <Import Project="mono-nunit-test.props" />\r
+    <Import Project="mono-test-env.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="mono.props" />\r
+    <Import Project="mono-test.props" />\r
+    <Import Project="mono-test-Win32.props" />\r
+    <Import Project="mono-nunit-test.props" />\r
+    <Import Project="mono-test-env.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="mono.props" />\r
+    <Import Project="mono-test.props" />\r
+    <Import Project="mono-test-x64.props" />\r
+    <Import Project="mono-nunit-test.props" />\r
+    <Import Project="mono-test-env.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="mono.props" />\r
+    <Import Project="mono-test.props" />\r
+    <Import Project="mono-test-x64.props" />\r
+    <Import Project="mono-nunit-test.props" />\r
+    <Import Project="mono-test-env.props" />\r
+  </ImportGroup>\r
+  <PropertyGroup Label="UserMacros" />\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <LinkIncremental>true</LinkIncremental>\r
+    <OutDir>$(MONO_BUILD_DIR_PREFIX)$(Platform)\lib\$(Configuration)\</OutDir>\r
+    <IntDir>$(MONO_BUILD_DIR_PREFIX)$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+    <LinkIncremental>true</LinkIncremental>\r
+    <OutDir>$(MONO_BUILD_DIR_PREFIX)$(Platform)\lib\$(Configuration)\</OutDir>\r
+    <IntDir>$(MONO_BUILD_DIR_PREFIX)$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <LinkIncremental>false</LinkIncremental>\r
+    <OutDir>$(MONO_BUILD_DIR_PREFIX)$(Platform)\lib\$(Configuration)\</OutDir>\r
+    <IntDir>$(MONO_BUILD_DIR_PREFIX)$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+    <LinkIncremental>false</LinkIncremental>\r
+    <OutDir>$(MONO_BUILD_DIR_PREFIX)$(Platform)\lib\$(Configuration)\</OutDir>\r
+    <IntDir>$(MONO_BUILD_DIR_PREFIX)$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+    <LocalDebuggerCommand>$(MONO_EXECUTABLE)</LocalDebuggerCommand>\r
+    <LocalDebuggerCommandArguments>$(MONO_NUNIT_RUN_ARGS)</LocalDebuggerCommandArguments>\r
+    <LocalDebuggerWorkingDirectory>$(MONO_NUNIT_TEST_DIR)</LocalDebuggerWorkingDirectory>\r
+    <LocalDebuggerEnvironment>$(MONO_PATH_ENV)\r
+$(MONO_CFG_DIR_ENV)\r
+$(MONO_TOOLCHAIN_PATH_ENV)\r
+$(MONO_LOG_LEVEL_ENV)\r
+$(MONO_LOG_MASK_ENV)\r
+$(LocalDebuggerEnvironment)</LocalDebuggerEnvironment>\r
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <LocalDebuggerCommand>$(MONO_EXECUTABLE)</LocalDebuggerCommand>\r
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>\r
+    <LocalDebuggerCommandArguments>$(MONO_NUNIT_RUN_ARGS)</LocalDebuggerCommandArguments>\r
+    <LocalDebuggerWorkingDirectory>$(MONO_NUNIT_TEST_DIR)</LocalDebuggerWorkingDirectory>\r
+    <LocalDebuggerEnvironment>$(MONO_PATH_ENV)\r
+$(MONO_CFG_DIR_ENV)\r
+$(MONO_TOOLCHAIN_PATH_ENV)\r
+$(MONO_LOG_LEVEL_ENV)\r
+$(MONO_LOG_MASK_ENV)\r
+$(LocalDebuggerEnvironment)</LocalDebuggerEnvironment>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <LocalDebuggerCommand>$(MONO_EXECUTABLE)</LocalDebuggerCommand>\r
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>\r
+    <LocalDebuggerCommandArguments>$(MONO_NUNIT_RUN_ARGS)</LocalDebuggerCommandArguments>\r
+    <LocalDebuggerWorkingDirectory>$(MONO_NUNIT_TEST_DIR)</LocalDebuggerWorkingDirectory>\r
+    <LocalDebuggerEnvironment>$(MONO_PATH_ENV)\r
+$(MONO_CFG_DIR_ENV)\r
+$(MONO_TOOLCHAIN_PATH_ENV)\r
+$(MONO_LOG_LEVEL_ENV)\r
+$(MONO_LOG_MASK_ENV)\r
+$(LocalDebuggerEnvironment)</LocalDebuggerEnvironment>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+    <LocalDebuggerCommand>$(MONO_EXECUTABLE)</LocalDebuggerCommand>\r
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>\r
+    <LocalDebuggerCommandArguments>$(MONO_NUNIT_RUN_ARGS)</LocalDebuggerCommandArguments>\r
+    <LocalDebuggerWorkingDirectory>$(MONO_NUNIT_TEST_DIR)</LocalDebuggerWorkingDirectory>\r
+    <LocalDebuggerEnvironment>$(MONO_PATH_ENV)\r
+$(MONO_CFG_DIR_ENV)\r
+$(MONO_TOOLCHAIN_PATH_ENV)\r
+$(MONO_LOG_LEVEL_ENV)\r
+$(MONO_LOG_MASK_ENV)\r
+$(LocalDebuggerEnvironment)</LocalDebuggerEnvironment>\r
+  </PropertyGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <ClCompile>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <Optimization>Disabled</Optimization>\r
+      <SDLCheck>true</SDLCheck>\r
+    </ClCompile>\r
+    <PreBuildEvent>\r
+      <Command>\r
+      </Command>\r
+    </PreBuildEvent>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+    <ClCompile>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <Optimization>Disabled</Optimization>\r
+      <SDLCheck>true</SDLCheck>\r
+    </ClCompile>\r
+    <PreBuildEvent>\r
+      <Command>\r
+      </Command>\r
+    </PreBuildEvent>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <ClCompile>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <IntrinsicFunctions>true</IntrinsicFunctions>\r
+      <SDLCheck>true</SDLCheck>\r
+    </ClCompile>\r
+    <Link>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+    </Link>\r
+    <PreBuildEvent>\r
+      <Command>\r
+      </Command>\r
+    </PreBuildEvent>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+    <ClCompile>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <IntrinsicFunctions>true</IntrinsicFunctions>\r
+      <SDLCheck>true</SDLCheck>\r
+    </ClCompile>\r
+    <Link>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+    </Link>\r
+    <PreBuildEvent>\r
+      <Command>\r
+      </Command>\r
+    </PreBuildEvent>\r
+  </ItemDefinitionGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
+  <ImportGroup Label="ExtensionTargets">\r
+  </ImportGroup>\r
+</Project>
\ No newline at end of file
index b298ce3a35bf5db82fd3e0617ecf8a8a89a63aad..51dcb2a5e6886574a6ea3ac5942a5077abddb8ee 100644 (file)
@@ -4,8 +4,8 @@
     <MONO_PATH_ENV>MONO_PATH=$(MONO_PATH)</MONO_PATH_ENV>
     <MONO_CFG_DIR_ENV>MONO_CFG_DIR=$(MONO_CFG_DIR)</MONO_CFG_DIR_ENV>
     <MONO_TOOLCHAIN_PATH_ENV>PATH=$(MONO_TOOLCHAIN_PATH)</MONO_TOOLCHAIN_PATH_ENV>
-    <MONO_LOG_LEVEL_ENV>MONO_LOG_LEVEL=debug</MONO_LOG_LEVEL_ENV>
-    <MONO_LOG_MASK_ENV>MONO_LOG_MASK=all</MONO_LOG_MASK_ENV>
+    <MONO_LOG_LEVEL_ENV>MONO_LOG_LEVEL=</MONO_LOG_LEVEL_ENV>
+    <MONO_LOG_MASK_ENV>MONO_LOG_MASK=</MONO_LOG_MASK_ENV>
   </PropertyGroup>
   <ItemGroup>
     <BuildMacro Include="MONO_PATH_ENV">
diff --git a/msvc/mono-testdriver-test.props b/msvc/mono-testdriver-test.props
new file mode 100644 (file)
index 0000000..1c03bbd
--- /dev/null
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Label="UserMacros">
+    <MONO_TESTDRIVER_TEST_DIR>$(MONO_DIR)/mono/tests</MONO_TESTDRIVER_TEST_DIR>
+    <MONO_PATH>$(MONO_PATH);$(MONO_TESTDRIVER_TEST_DIR)</MONO_PATH>
+       <MONO_CONFIG_PATH>$(MONO_EXECUTABLE_DIR)\tests-config.xml</MONO_CONFIG_PATH>
+    <MONO_CONFIG_ARG>--config "$(MONO_CONFIG_PATH)"</MONO_CONFIG_ARG>
+    <MONO_TESTDRIVER_RUN_TARGET>winx64structs.exe</MONO_TESTDRIVER_RUN_TARGET>
+    <MONO_TESTDRIVER_RUN_ADDITIONAL_ARGS>
+    </MONO_TESTDRIVER_RUN_ADDITIONAL_ARGS>
+    <MONO_TESTDRIVER_RUN_ARGS>$(MONO_CONFIG_ARG) "$(MONO_TESTDRIVER_RUN_TARGET)" $(MONO_TESTDRIVER_RUN_ADDITIONAL_ARGS)</MONO_TESTDRIVER_RUN_ARGS>
+  </PropertyGroup>
+  <ItemGroup>
+    <BuildMacro Include="MONO_TESTDRIVER_TEST_DIR">
+      <Value>$(MONO_TESTDRIVER_TEST_DIR)</Value>
+    </BuildMacro>
+    <BuildMacro Include="MONO_PATH">
+      <Value>$(MONO_PATH)</Value>
+    </BuildMacro>
+       <BuildMacro Include="MONO_CONFIG_PATH">
+      <Value>$(MONO_CONFIG_PATH)</Value>
+    </BuildMacro>
+    <BuildMacro Include="MONO_CONFIG_ARG">
+      <Value>$(MONO_CONFIG_ARG)</Value>
+    </BuildMacro>
+    <BuildMacro Include="MONO_TESTDRIVER_RUN_TARGET">
+      <Value>$(MONO_TESTDRIVER_RUN_TARGET)</Value>
+    </BuildMacro>
+    <BuildMacro Include="MONO_TESTDRIVER_RUN_ADDITIONAL_ARGS">
+      <Value>$(MONO_TESTDRIVER_RUN_ADDITIONAL_ARGS)</Value>
+    </BuildMacro>
+    <BuildMacro Include="MONO_TESTDRIVER_RUN_ARGS">
+      <Value>$(MONO_TESTDRIVER_RUN_ARGS)</Value>
+    </BuildMacro>
+  </ItemGroup>
+  <ItemDefinitionGroup />
+</Project>
\ No newline at end of file
diff --git a/msvc/mono-testdriver-test.vcxproj b/msvc/mono-testdriver-test.vcxproj
new file mode 100644 (file)
index 0000000..fce7b4d
--- /dev/null
@@ -0,0 +1,220 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup Label="ProjectConfigurations">\r
+    <ProjectConfiguration Include="Debug|Win32">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Win32">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug|x64">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|x64">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ProjectReference Include="mono.vcxproj">\r
+      <Project>{a0eddcd9-940f-432c-a28f-7ef322437d79}</Project>\r
+    </ProjectReference>\r
+  </ItemGroup>\r
+  <PropertyGroup Label="Globals">\r
+    <ProjectGuid>{7BECCFA0-28A0-4995-9856-558560F720E6}</ProjectGuid>\r
+    <Keyword>Win32Proj</Keyword>\r
+    <RootNamespace>monotestdrivertest</RootNamespace>\r
+    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
+    <ConfigurationType>Utility</ConfigurationType>\r
+    <UseDebugLibraries>true</UseDebugLibraries>\r
+    <PlatformToolset>v140</PlatformToolset>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
+    <ConfigurationType>Utility</ConfigurationType>\r
+    <UseDebugLibraries>false</UseDebugLibraries>\r
+    <PlatformToolset>v140</PlatformToolset>\r
+    <WholeProgramOptimization>true</WholeProgramOptimization>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">\r
+    <ConfigurationType>Utility</ConfigurationType>\r
+    <UseDebugLibraries>true</UseDebugLibraries>\r
+    <PlatformToolset>v140</PlatformToolset>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">\r
+    <ConfigurationType>Utility</ConfigurationType>\r
+    <UseDebugLibraries>false</UseDebugLibraries>\r
+    <PlatformToolset>v140</PlatformToolset>\r
+    <WholeProgramOptimization>true</WholeProgramOptimization>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
+  <ImportGroup Label="ExtensionSettings">\r
+  </ImportGroup>\r
+  <ImportGroup Label="Shared">\r
+  </ImportGroup>\r
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="mono.props" />\r
+    <Import Project="mono-test.props" />\r
+    <Import Project="mono-test-Win32.props" />\r
+    <Import Project="mono-testdriver-test.props" />\r
+    <Import Project="mono-test-env.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="mono.props" />\r
+    <Import Project="mono-test.props" />\r
+    <Import Project="mono-test-Win32.props" />\r
+    <Import Project="mono-testdriver-test.props" />\r
+    <Import Project="mono-test-env.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="mono.props" />\r
+    <Import Project="mono-test.props" />\r
+    <Import Project="mono-test-x64.props" />\r
+    <Import Project="mono-testdriver-test.props" />\r
+    <Import Project="mono-test-env.props" />\r
+  </ImportGroup>\r
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+    <Import Project="mono.props" />\r
+    <Import Project="mono-test.props" />\r
+    <Import Project="mono-test-x64.props" />\r
+    <Import Project="mono-testdriver-test.props" />\r
+    <Import Project="mono-test-env.props" />\r
+  </ImportGroup>\r
+  <PropertyGroup Label="UserMacros" />\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <LinkIncremental>true</LinkIncremental>\r
+    <OutDir>$(MONO_BUILD_DIR_PREFIX)$(Platform)\lib\$(Configuration)\</OutDir>\r
+    <IntDir>$(MONO_BUILD_DIR_PREFIX)$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+    <LinkIncremental>true</LinkIncremental>\r
+    <OutDir>$(MONO_BUILD_DIR_PREFIX)$(Platform)\lib\$(Configuration)\</OutDir>\r
+    <IntDir>$(MONO_BUILD_DIR_PREFIX)$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <LinkIncremental>false</LinkIncremental>\r
+    <OutDir>$(MONO_BUILD_DIR_PREFIX)$(Platform)\lib\$(Configuration)\</OutDir>\r
+    <IntDir>$(MONO_BUILD_DIR_PREFIX)$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+    <LinkIncremental>false</LinkIncremental>\r
+    <OutDir>$(MONO_BUILD_DIR_PREFIX)$(Platform)\lib\$(Configuration)\</OutDir>\r
+    <IntDir>$(MONO_BUILD_DIR_PREFIX)$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+    <LocalDebuggerCommand>$(MONO_EXECUTABLE)</LocalDebuggerCommand>\r
+    <LocalDebuggerCommandArguments>$(MONO_TESTDRIVER_RUN_ARGS)</LocalDebuggerCommandArguments>\r
+    <LocalDebuggerWorkingDirectory>$(MONO_TESTDRIVER_TEST_DIR)</LocalDebuggerWorkingDirectory>\r
+    <LocalDebuggerEnvironment>$(MONO_PATH_ENV)\r
+$(MONO_CFG_DIR_ENV)\r
+$(MONO_TOOLCHAIN_PATH_ENV)\r
+$(MONO_LOG_LEVEL_ENV)\r
+$(MONO_LOG_MASK_ENV)\r
+$(LocalDebuggerEnvironment)</LocalDebuggerEnvironment>\r
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <LocalDebuggerCommand>$(MONO_EXECUTABLE)</LocalDebuggerCommand>\r
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>\r
+    <LocalDebuggerCommandArguments>$(MONO_TESTDRIVER_RUN_ARGS)</LocalDebuggerCommandArguments>\r
+    <LocalDebuggerWorkingDirectory>$(MONO_TESTDRIVER_TEST_DIR)</LocalDebuggerWorkingDirectory>\r
+    <LocalDebuggerEnvironment>$(MONO_PATH_ENV)\r
+$(MONO_CFG_DIR_ENV)\r
+$(MONO_TOOLCHAIN_PATH_ENV)\r
+$(MONO_LOG_LEVEL_ENV)\r
+$(MONO_LOG_MASK_ENV)\r
+$(LocalDebuggerEnvironment)</LocalDebuggerEnvironment>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <LocalDebuggerCommand>$(MONO_EXECUTABLE)</LocalDebuggerCommand>\r
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>\r
+    <LocalDebuggerCommandArguments>$(MONO_TESTDRIVER_RUN_ARGS)</LocalDebuggerCommandArguments>\r
+    <LocalDebuggerWorkingDirectory>$(MONO_TESTDRIVER_TEST_DIR)</LocalDebuggerWorkingDirectory>\r
+    <LocalDebuggerEnvironment>$(MONO_PATH_ENV)\r
+$(MONO_CFG_DIR_ENV)\r
+$(MONO_TOOLCHAIN_PATH_ENV)\r
+$(MONO_LOG_LEVEL_ENV)\r
+$(MONO_LOG_MASK_ENV)\r
+$(LocalDebuggerEnvironment)</LocalDebuggerEnvironment>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+    <LocalDebuggerCommand>$(MONO_EXECUTABLE)</LocalDebuggerCommand>\r
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>\r
+    <LocalDebuggerCommandArguments>$(MONO_TESTDRIVER_RUN_ARGS)</LocalDebuggerCommandArguments>\r
+    <LocalDebuggerWorkingDirectory>$(MONO_TESTDRIVER_TEST_DIR)</LocalDebuggerWorkingDirectory>\r
+    <LocalDebuggerEnvironment>$(MONO_PATH_ENV)\r
+$(MONO_CFG_DIR_ENV)\r
+$(MONO_TOOLCHAIN_PATH_ENV)\r
+$(MONO_LOG_LEVEL_ENV)\r
+$(MONO_LOG_MASK_ENV)\r
+$(LocalDebuggerEnvironment)</LocalDebuggerEnvironment>\r
+  </PropertyGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <ClCompile>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <Optimization>Disabled</Optimization>\r
+      <SDLCheck>true</SDLCheck>\r
+    </ClCompile>\r
+    <PreBuildEvent>\r
+      <Command>test-config-setup.bat "$(MONO_CONFIG_PATH)" "$(MONO_EXECUTABLE_DIR)" x86</Command>\r
+    </PreBuildEvent>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+    <ClCompile>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <Optimization>Disabled</Optimization>\r
+      <SDLCheck>true</SDLCheck>\r
+    </ClCompile>\r
+    <PreBuildEvent>\r
+      <Command>test-config-setup.bat "$(MONO_CONFIG_PATH)" "$(MONO_EXECUTABLE_DIR)" x86-64</Command>\r
+    </PreBuildEvent>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <ClCompile>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <IntrinsicFunctions>true</IntrinsicFunctions>\r
+      <SDLCheck>true</SDLCheck>\r
+    </ClCompile>\r
+    <Link>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+    </Link>\r
+    <PreBuildEvent>\r
+      <Command>test-config-setup.bat "$(MONO_CONFIG_PATH)" "$(MONO_EXECUTABLE_DIR)" x86</Command>\r
+    </PreBuildEvent>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+    <ClCompile>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <IntrinsicFunctions>true</IntrinsicFunctions>\r
+      <SDLCheck>true</SDLCheck>\r
+    </ClCompile>\r
+    <Link>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+    </Link>\r
+    <PreBuildEvent>\r
+      <Command>test-config-setup.bat "$(MONO_CONFIG_PATH)" "$(MONO_EXECUTABLE_DIR)" x86-64</Command>\r
+    </PreBuildEvent>\r
+  </ItemDefinitionGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
+  <ImportGroup Label="ExtensionTargets">\r
+  </ImportGroup>\r
+</Project>
\ No newline at end of file
diff --git a/msvc/mono-testdriver-test.vcxproj.filters b/msvc/mono-testdriver-test.vcxproj.filters
new file mode 100644 (file)
index 0000000..ef1ebf5
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
\ No newline at end of file
index 5384dc846b4cb2c0ee72d1e25695c04c47c44898..abc81a55abd8fb65449c0a008f6696c2feeab76e 100644 (file)
@@ -13,6 +13,8 @@
     <MONO_USE_SEPARATE_BUILD_DIR>true</MONO_USE_SEPARATE_BUILD_DIR>
     <!-- When true, all binaries and libraries will link using static c-runtime. When false, all binaries and libraries will link using dynamic c-runtime.  -->
     <MONO_USE_STATIC_C_RUNTIME>false</MONO_USE_STATIC_C_RUNTIME>
+    <!-- When true, mono binaries will link using static libmono. When false, mono binaries will link using dynamic libmono.  -->
+    <MONO_USE_STATIC_LIBMONO>false</MONO_USE_STATIC_LIBMONO>
   </PropertyGroup>
   <PropertyGroup Label="MonoDirectories">
     <top_srcdir>$(MSBuildProjectDirectory)/..</top_srcdir>
     <MONO_TARGET_SUFFIX Condition="'$(MONO_USE_TARGET_SUFFIX)'=='true'">-boehm</MONO_TARGET_SUFFIX>
     <MONO_BUILD_DIR_PREFIX Condition="'$(MONO_USE_SEPARATE_BUILD_DIR)'=='true'">$(MONO_BUILD_DIR_PREFIX)boehm/</MONO_BUILD_DIR_PREFIX>
   </PropertyGroup>
+  <PropertyGroup Label="Static-Mono-Libraries">
+    <MONO_RUNTIME_LIBS>libmonoutils.lib;libmonoruntime$(MONO_TARGET_SUFFIX).lib;$(GC_LIB)</MONO_RUNTIME_LIBS>
+    <MONO_STATIC_LIBMONO_LIB>libmono-static$(MONO_TARGET_SUFFIX).lib;$(MONO_RUNTIME_LIBS)</MONO_STATIC_LIBMONO_LIB>
+    <MONO_DYNAMIC_LIBMONO_LIB>mono-2.0$(MONO_TARGET_SUFFIX).lib</MONO_DYNAMIC_LIBMONO_LIB>
+  </PropertyGroup>
+  <PropertyGroup Label="Static-libmono-Library" Condition="$(MONO_USE_STATIC_LIBMONO)=='true'">
+    <MONO_LIBMONO_LIB>$(MONO_STATIC_LIBMONO_LIB)</MONO_LIBMONO_LIB>
+  </PropertyGroup>
+  <PropertyGroup Label="Dynamic-libmono-Library" Condition="$(MONO_USE_STATIC_LIBMONO)!='true'">
+    <MONO_LIBMONO_LIB>$(MONO_DYNAMIC_LIBMONO_LIB)</MONO_LIBMONO_LIB>
+  </PropertyGroup>
   <PropertyGroup Label="MonoProfiler">
     <VTUNE_INCLUDE_DIR>$(ProgramFiles)/Intel/VTune Amplifier XE 2013/include</VTUNE_INCLUDE_DIR>
   </PropertyGroup>
@@ -73,6 +86,9 @@
     <BuildMacro Include="MONO_USE_STATIC_C_RUNTIME">
       <Value>$(MONO_USE_STATIC_C_RUNTIME)</Value>
     </BuildMacro>
+    <BuildMacro Include="MONO_USE_STATIC_LIBMONO">
+      <Value>$(MONO_USE_STATIC_LIBMONO)</Value>
+    </BuildMacro>
   </ItemGroup>
   <ItemDefinitionGroup>
     <ClCompile>
index 9ab545de68956fc0ba88c60e673dbd18f010dd1f..0dcd61f4c59cd4fde9fcf70ed3c7812c8c9ae067 100644 (file)
@@ -157,7 +157,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgcmonosgen", "libgcmonos
 EndProject\r
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mono-mini-regression-test", "mono-mini-regression-test.vcxproj", "{3E0D229E-C39F-4EDA-9A6A-A33ECEA0322D}"\r
 EndProject\r
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "regression", "regression", "{A0068765-334B-414C-8E21-8376CD2EC9F6}"\r
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "jit", "jit", "{A0068765-334B-414C-8E21-8376CD2EC9F6}"\r
 EndProject\r
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmono-static", "libmono-static.vcxproj", "{CB0D9E92-293C-439C-9AC7-C5F59B6E0772}"\r
 EndProject\r
@@ -167,6 +167,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mono-full-aot-compile-test"
 EndProject\r
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mono-full-aot-run-test", "mono-full-aot-run-test.vcxproj", "{6C64262B-077B-4E12-AF91-9409ECCB75F6}"\r
 EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mono-testdriver-test", "mono-testdriver-test.vcxproj", "{7BECCFA0-28A0-4995-9856-558560F720E6}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mono-nunit-test", "mono-nunit-test.vcxproj", "{0046B994-40A8-4C64-AC9D-429DC9177B54}"\r
+EndProject\r
 Global\r
        GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
                Debug|Win32 = Debug|Win32\r
@@ -373,6 +377,22 @@ Global
                {6C64262B-077B-4E12-AF91-9409ECCB75F6}.Release|Win32.Build.0 = Release|Win32\r
                {6C64262B-077B-4E12-AF91-9409ECCB75F6}.Release|x64.ActiveCfg = Release|x64\r
                {6C64262B-077B-4E12-AF91-9409ECCB75F6}.Release|x64.Build.0 = Release|x64\r
+               {7BECCFA0-28A0-4995-9856-558560F720E6}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {7BECCFA0-28A0-4995-9856-558560F720E6}.Debug|Win32.Build.0 = Debug|Win32\r
+               {7BECCFA0-28A0-4995-9856-558560F720E6}.Debug|x64.ActiveCfg = Debug|x64\r
+               {7BECCFA0-28A0-4995-9856-558560F720E6}.Debug|x64.Build.0 = Debug|x64\r
+               {7BECCFA0-28A0-4995-9856-558560F720E6}.Release|Win32.ActiveCfg = Release|Win32\r
+               {7BECCFA0-28A0-4995-9856-558560F720E6}.Release|Win32.Build.0 = Release|Win32\r
+               {7BECCFA0-28A0-4995-9856-558560F720E6}.Release|x64.ActiveCfg = Release|x64\r
+               {7BECCFA0-28A0-4995-9856-558560F720E6}.Release|x64.Build.0 = Release|x64\r
+               {0046B994-40A8-4C64-AC9D-429DC9177B54}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {0046B994-40A8-4C64-AC9D-429DC9177B54}.Debug|Win32.Build.0 = Debug|Win32\r
+               {0046B994-40A8-4C64-AC9D-429DC9177B54}.Debug|x64.ActiveCfg = Debug|x64\r
+               {0046B994-40A8-4C64-AC9D-429DC9177B54}.Debug|x64.Build.0 = Debug|x64\r
+               {0046B994-40A8-4C64-AC9D-429DC9177B54}.Release|Win32.ActiveCfg = Release|Win32\r
+               {0046B994-40A8-4C64-AC9D-429DC9177B54}.Release|Win32.Build.0 = Release|Win32\r
+               {0046B994-40A8-4C64-AC9D-429DC9177B54}.Release|x64.ActiveCfg = Release|x64\r
+               {0046B994-40A8-4C64-AC9D-429DC9177B54}.Release|x64.Build.0 = Release|x64\r
        EndGlobalSection\r
        GlobalSection(SolutionProperties) = preSolution\r
                HideSolutionNode = FALSE\r
@@ -407,6 +427,8 @@ Global
                {BACF489E-EAEB-42BF-9E0A-C54D7CF455B4} = {ECA11C76-E192-4F67-A8FA-28B637D9716F}\r
                {C7D83158-4EB6-4409-8730-612AD45FAF6A} = {BACF489E-EAEB-42BF-9E0A-C54D7CF455B4}\r
                {6C64262B-077B-4E12-AF91-9409ECCB75F6} = {BACF489E-EAEB-42BF-9E0A-C54D7CF455B4}\r
+               {7BECCFA0-28A0-4995-9856-558560F720E6} = {A0068765-334B-414C-8E21-8376CD2EC9F6}\r
+               {0046B994-40A8-4C64-AC9D-429DC9177B54} = {A0068765-334B-414C-8E21-8376CD2EC9F6}\r
        EndGlobalSection\r
        GlobalSection(ExtensibilityGlobals) = postSolution\r
                AMDCaProjectFile = C:\Users\Owner\Development\monogit\mono\msvc\CodeAnalyst\mono.caw\r
index 12cceebe601e6c6be260770cff6f7ef0598e753a..f277f33258b4902a3d14f6249a026c24501ee912 100644 (file)
     </ClCompile>\r
     <ProjectReference />\r
     <Link>\r
-      <AdditionalDependencies>eglib.lib;mono-2.0$(MONO_TARGET_SUFFIX).lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>eglib.lib;$(MONO_LIBMONO_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>eglib.lib;mono-2.0$(MONO_TARGET_SUFFIX).lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>eglib.lib;$(MONO_LIBMONO_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>eglib.lib;mono-2.0$(MONO_TARGET_SUFFIX).lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>eglib.lib;$(MONO_LIBMONO_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <SubSystem>Console</SubSystem>\r
       <OptimizeReferences>true</OptimizeReferences>\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>eglib.lib;mono-2.0$(MONO_TARGET_SUFFIX).lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>eglib.lib;$(MONO_LIBMONO_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
index 7e7eb2df1552132be1d5f91f13028c9ee2f631ff..7f14c93115fca10fa728f62d78fb86f5afdaa9de 100644 (file)
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>eglib.lib;libmonoruntime$(MONO_TARGET_SUFFIX).lib;libmonoutils.lib;$(GC_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>eglib.lib;$(MONO_RUNTIME_LIBS);%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
       <DataExecutionPrevention>\r
       </DataExecutionPrevention>\r
       <TargetMachine>MachineX86</TargetMachine>\r
-      <AdditionalDependencies>eglib.lib;libmonoruntime$(MONO_TARGET_SUFFIX).lib;libmonoutils.lib;$(GC_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>eglib.lib;$(MONO_RUNTIME_LIBS);%(AdditionalDependencies)</AdditionalDependencies>\r
     </Link>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>eglib.lib;libmonoruntime$(MONO_TARGET_SUFFIX).lib;libmonoutils.lib;$(GC_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>eglib.lib;$(MONO_RUNTIME_LIBS);%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
       <OptimizeReferences>true</OptimizeReferences>\r
       <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
       <TargetMachine>MachineX64</TargetMachine>\r
-      <AdditionalDependencies>eglib.lib;libmonoruntime$(MONO_TARGET_SUFFIX).lib;libmonoutils.lib;$(GC_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>eglib.lib;$(MONO_RUNTIME_LIBS);%(AdditionalDependencies)</AdditionalDependencies>\r
     </Link>\r
   </ItemDefinitionGroup>\r
   <ItemGroup>\r
index cce843fff837109d89404089ffbf4356c2d69fba..ce3658dd42cb5e0e5e8e514ac538c4dd5e076eca 100644 (file)
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>eglib.lib;mono-2.0$(MONO_TARGET_SUFFIX).lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>eglib.lib;$(MONO_LIBMONO_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
       <DataExecutionPrevention>\r
       </DataExecutionPrevention>\r
       <TargetMachine>MachineX86</TargetMachine>\r
-      <AdditionalDependencies>eglib.lib;mono-2.0$(MONO_TARGET_SUFFIX).lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>eglib.lib;$(MONO_LIBMONO_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
     </Link>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>eglib.lib;mono-2.0$(MONO_TARGET_SUFFIX).lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>eglib.lib;$(MONO_LIBMONO_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
       <OptimizeReferences>true</OptimizeReferences>\r
       <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
       <TargetMachine>MachineX64</TargetMachine>\r
-      <AdditionalDependencies>eglib.lib;mono-2.0$(MONO_TARGET_SUFFIX).lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>eglib.lib;$(MONO_LIBMONO_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
     </Link>\r
   </ItemDefinitionGroup>\r
   <ItemGroup>\r
index 45c497b9bdc31612d3d1fbd4a95b2bdd7041ba50..544a89d32a2bb0a27ec120f80b791caf98a5bd9f 100644 (file)
       <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
       <TargetMachine>MachineX86</TargetMachine>\r
       <ModuleDefinitionFile>mono-profiler-vtune.def</ModuleDefinitionFile>\r
-      <AdditionalDependencies>mono-2.0$(MONO_TARGET_SUFFIX).lib;$(GC_LIB);eglib.lib;jitprofiling.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>$(MONO_LIBMONO_LIB);$(GC_LIB);eglib.lib;jitprofiling.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(ProgramFiles)\Intel\VTune Amplifier XE 2013\lib32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
     </Link>\r
     <ProjectReference>\r
       <OptimizeReferences>true</OptimizeReferences>\r
       <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
       <ModuleDefinitionFile>mono-profiler-vtune.def</ModuleDefinitionFile>\r
-      <AdditionalDependencies>mono-2.0$(MONO_TARGET_SUFFIX).lib;$(GC_LIB);eglib.lib;jitprofiling.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>$(MONO_LIBMONO_LIB);$(GC_LIB);eglib.lib;jitprofiling.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(ProgramFiles)\Intel\VTune Amplifier XE 2013\lib32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
     </Link>\r
     <ProjectReference>\r
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
     </ClCompile>\r
     <Link>\r
-      <AdditionalDependencies>mono-2.0$(MONO_TARGET_SUFFIX).lib;$(GC_LIB);eglib.lib;jitprofiling.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>$(MONO_LIBMONO_LIB);$(GC_LIB);eglib.lib;jitprofiling.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(ProgramFiles)\Intel\VTune Amplifier XE 2013\lib32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Windows</SubSystem>\r
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
     </ClCompile>\r
     <Link>\r
-      <AdditionalDependencies>mono-2.0$(MONO_TARGET_SUFFIX).lib;$(GC_LIB);eglib.lib;jitprofiling.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>$(MONO_LIBMONO_LIB);$(GC_LIB);eglib.lib;jitprofiling.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>$(ProgramFiles)\Intel\VTune Amplifier XE 2013\lib32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Windows</SubSystem>\r
diff --git a/msvc/test-config-setup.bat b/msvc/test-config-setup.bat
new file mode 100644 (file)
index 0000000..adb174d
--- /dev/null
@@ -0,0 +1,56 @@
+@ECHO off
+
+SET MONO_RESULT=1
+SET CONFIG_PATH=%1
+SET MONO_MODULE_PATH=%2
+SET CPU_ARCH=%3
+
+IF "" == "%CONFIG_PATH%" (
+       ECHO Error: No configuration path set.
+       GOTO ON_ERROR
+)
+
+IF "" == "%MONO_MODULE_PATH%" (
+       ECHO Error: No mono module path set.
+       GOTO ON_ERROR
+)
+
+IF "" == "%CPU_ARCH%" (
+       ECHO Error: No cpu architecture set.
+       GOTO ON_ERROR
+)
+
+IF NOT "x86" == "%CPU_ARCH%" (
+
+       IF NOT "x86-64" == "%CPU_ARCH%" (
+               ECHO Error: Unknown cpu architecture, %CPU_ARCH%.
+               GOTO ON_ERROR
+       )
+)
+
+SET CONFIG_PATH=%CONFIG_PATH:"=%
+SET CONFIG_PATH=%CONFIG_PATH:/=\%
+
+SET MONO_MODULE_PATH=%MONO_MODULE_PATH:"=%
+SET MONO_MODULE_PATH=%MONO_MODULE_PATH:/=\%
+
+REM Setup test configuration file.
+>%CONFIG_PATH% ECHO ^<configuration^>
+>>%CONFIG_PATH% ECHO ^<dllmap os="windows" cpu="%CPU_ARCH%" dll="libtest" target="%MONO_MODULE_PATH%\libtest.dll" /^>
+>>%CONFIG_PATH% ECHO ^</configuration^>
+
+SET MONO_RESULT=0
+ECHO Successfully setup test configuration file, %CONFIG_PATH%.
+
+GOTO ON_EXIT
+
+:ON_ERROR
+       ECHO Failed to setup test configuration file.
+       ECHO test-config-setup.bat [CONFIG_FILE_PATH] [MONO_MODULE_PATH] [x86|x86-64]
+       SET MONO_RESULT=1
+       GOTO ON_EXIT
+       
+:ON_EXIT
+       EXIT /b %MONO_RESULT%
+
+@ECHO on
index 06ad062761f931b6d9efb5ed880536f88741b425..f258fb673c65cf75f2bcee1ed5179608c7baaa2a 100644 (file)
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>mono-2.0$(MONO_TARGET_SUFFIX).lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>$(MONO_DYNAMIC_LIBMONO_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
       <DataExecutionPrevention>\r
       </DataExecutionPrevention>\r
       <TargetMachine>MachineX86</TargetMachine>\r
-      <AdditionalDependencies>mono-2.0$(MONO_TARGET_SUFFIX).lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>$(MONO_DYNAMIC_LIBMONO_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
     </Link>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>mono-2.0$(MONO_TARGET_SUFFIX).lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>$(MONO_DYNAMIC_LIBMONO_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
       <OptimizeReferences>true</OptimizeReferences>\r
       <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
       <TargetMachine>MachineX64</TargetMachine>\r
-      <AdditionalDependencies>mono-2.0$(MONO_TARGET_SUFFIX).lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>$(MONO_DYNAMIC_LIBMONO_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
     </Link>\r
   </ItemDefinitionGroup>\r
   <ItemGroup>\r
index 31411b0df6193224ec03e5f28a99bd440928a3ba..810f82f82fa93894eddc640d2de9388582f9c53b 100644 (file)
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>mono-2.0$(MONO_TARGET_SUFFIX).lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>$(MONO_DYNAMIC_LIBMONO_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
       <DataExecutionPrevention>\r
       </DataExecutionPrevention>\r
       <TargetMachine>MachineX86</TargetMachine>\r
-      <AdditionalDependencies>mono-2.0$(MONO_TARGET_SUFFIX).lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>$(MONO_DYNAMIC_LIBMONO_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
     </Link>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>mono-2.0$(MONO_TARGET_SUFFIX).lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>$(MONO_DYNAMIC_LIBMONO_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
       <OptimizeReferences>true</OptimizeReferences>\r
       <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
       <TargetMachine>MachineX64</TargetMachine>\r
-      <AdditionalDependencies>mono-2.0$(MONO_TARGET_SUFFIX).lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>$(MONO_DYNAMIC_LIBMONO_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
     </Link>\r
   </ItemDefinitionGroup>\r
   <ItemGroup>\r
index cd9433f8b1af0d5e3afe56396b78f2ac1f2e51d7..5fac6d8ac2349d1007bca1c36a2efdf3b8259c31 100644 (file)
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>mono-2.0$(MONO_TARGET_SUFFIX).lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>$(MONO_DYNAMIC_LIBMONO_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
       <DataExecutionPrevention>\r
       </DataExecutionPrevention>\r
       <TargetMachine>MachineX86</TargetMachine>\r
-      <AdditionalDependencies>mono-2.0$(MONO_TARGET_SUFFIX).lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>$(MONO_DYNAMIC_LIBMONO_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
     </Link>\r
   </ItemDefinitionGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
       <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
     </ProjectReference>\r
     <Link>\r
-      <AdditionalDependencies>mono-2.0$(MONO_TARGET_SUFFIX).lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>$(MONO_DYNAMIC_LIBMONO_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
       <GenerateDebugInformation>true</GenerateDebugInformation>\r
       <SubSystem>Console</SubSystem>\r
       <OptimizeReferences>true</OptimizeReferences>\r
       <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
       <TargetMachine>MachineX64</TargetMachine>\r
-      <AdditionalDependencies>mono-2.0$(MONO_TARGET_SUFFIX).lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalDependencies>$(MONO_DYNAMIC_LIBMONO_LIB);%(AdditionalDependencies)</AdditionalDependencies>\r
     </Link>\r
   </ItemDefinitionGroup>\r
   <ItemGroup>\r
index a05395ca491b2fa58eabf042b27bd7116a848737..f25016fd5f5e872c9e58c95ae6e5779cfb2d8e6d 100755 (executable)
@@ -26,15 +26,15 @@ IF EXIST %EGLIB_CONFIG_H% (
        )
 )
 
-%windir%\system32\WindowsPowerShell\v1.0\powershell.exe -executionpolicy bypass -NonInteractive -File compare-config-files.ps1 %WIN_CONFIG_H% %CONFIG_H% %CONFIGURE_AC% >$null 2>&1
+%windir%\system32\WindowsPowerShell\v1.0\powershell.exe -executionpolicy bypass -NonInteractive -File compare-config-files.ps1 %WIN_CONFIG_H% %CONFIG_H% %CONFIGURE_AC% 2>&1
 
 IF NOT %ERRORLEVEL% == 0 (
        ECHO copy %WIN_CONFIG_H% %CONFIG_H%
        copy %WIN_CONFIG_H% %CONFIG_H%
-       %windir%\system32\WindowsPowerShell\v1.0\powershell.exe -NonInteractive -Command "(Get-Content %CONFIG_H%) -replace '#MONO_VERSION#', (Select-String -path %CONFIGURE_AC% -pattern 'AC_INIT\(mono, \[(.*)\]').Matches[0].Groups[1].Value | Set-Content %CONFIG_H%" >$null 2>&1
+       %windir%\system32\WindowsPowerShell\v1.0\powershell.exe -NonInteractive -Command "(Get-Content %CONFIG_H%) -replace '#MONO_VERSION#', (Select-String -path %CONFIGURE_AC% -pattern 'AC_INIT\(mono, \[(.*)\]').Matches[0].Groups[1].Value | Set-Content %CONFIG_H%" 2>&1
 )
 
-%windir%\system32\WindowsPowerShell\v1.0\powershell.exe -executionpolicy bypass -NonInteractive -File compare-config-files.ps1 %EGLIB_WIN_CONFIG_H% %EGLIB_CONFIG_H% >$null 2>&1
+%windir%\system32\WindowsPowerShell\v1.0\powershell.exe -executionpolicy bypass -NonInteractive -File compare-config-files.ps1 %EGLIB_WIN_CONFIG_H% %EGLIB_CONFIG_H% 2>&1
 
 IF NOT %ERRORLEVEL% == 0 (
        ECHO copy %EGLIB_WIN_CONFIG_H% %EGLIB_CONFIG_H%
@@ -42,7 +42,7 @@ IF NOT %ERRORLEVEL% == 0 (
 )
 
 SET VERSION_CONTENT="#define FULL_VERSION \"Visual Studio built mono\""
-%windir%\system32\WindowsPowerShell\v1.0\powershell.exe -executionpolicy bypass -NonInteractive -File compare-config-content.ps1 %VERSION_CONTENT% %VERSION_H%
+%windir%\system32\WindowsPowerShell\v1.0\powershell.exe -executionpolicy bypass -NonInteractive -File compare-config-content.ps1 %VERSION_CONTENT% %VERSION_H%  2>&1
 
 
 IF NOT %ERRORLEVEL% == 0 (
index b202c2493fb11fac4ff3acf6dce92f6ecb56e979..74f0d1bbf386169c651b16b7ff4828e506e0bf64 100755 (executable)
@@ -59,6 +59,11 @@ if [[ -n "${ghprbPullId}" ]] && [[ ${label} == w* ]];
 fi
 
 if [[ ${CI_TAGS} == *'acceptance-tests'* ]];
-then $(dirname "${BASH_SOURCE[0]}")/run-test-acceptance-tests.sh
-else make check-ci
-fi
\ No newline at end of file
+    then
+       $(dirname "${BASH_SOURCE[0]}")/run-test-acceptance-tests.sh
+elif [[ ${CI_TAGS} == *'profiler-stress-tests'* ]];
+    then
+       $(dirname "${BASH_SOURCE[0]}")/run-test-profiler-stress-tests.sh
+else
+       make check-ci
+fi
diff --git a/scripts/ci/run-test-profiler-stress-tests.sh b/scripts/ci/run-test-profiler-stress-tests.sh
new file mode 100755 (executable)
index 0000000..52d6f16
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/bash -e
+
+export TESTCMD=`dirname "${BASH_SOURCE[0]}"`/run-step.sh
+
+${TESTCMD} --label=check-profiler-stress --timeout=20h make -C acceptance-tests check-profiler-stress